Android Dagger-2, как обеспечить зависимость для параметров метода
У меня есть модуль FragmentModule
@Module
public class FragmentModule
{
@Provides
public static PickerDashboardFragment providesPickerDashboard(int status, String name, Object someComplexObject)
{
PickerDashboardFragment fragment = new PickerDashboardFragment();
Bundle b = new Bundle();
b.putInt("status", status);
b.putString("name", name);
b.putInt("object", someComplexObject);
fragment.setArguments(bundle);
return fragment;
}
@Provides
public static PickingFragment providesPickingFragment()
{
PickingFragment fragment = new PickingFragment();
return fragment;
}
}
Вот мой класс компонентов
@Component(modules = {UtilModule.class, FragmentModule.class})
public interface ApplicationComponent
{
void inject(PickerDashboardActivity target);
}
В моей деятельности это то, как я делаю инъекцию PickerDashboardActivity
@Inject
PickerDashboardFragment frag;
ApplicationComponent component = DaggerApplicationComponent.builder().build();
component.inject(this);
Мой вопрос заключается в том, что является лучшим и простым способом предоставления зависимостей для PickerDashboardFragment providesPickerDashboard(int status, String name, Object someComplexObject)
т.е. статус, имя и некоторый сложный объект.
С уважением
2 ответа
Добавить атрибуты и Provides
методы для вашего модуля, как это:
@Module
public class FragmentModule
{
private final int status;
private final String name;
private final Object someComplexObject;
public FragmentModule(int status, String name, Object someComplexObject) {
this.status = status;
this.name = name;
this.someComplexObject = someComplexObject;
}
@Provides
int providesStatus() {
return status;
}
@Provides
String providesName() {
return name;
}
@Provides
Object providesSomeComplexObject() {
return someComplexObjext;
}
@Provides
public static PickerDashboardFragment providesPickerDashboard(int status, String name, Object someComplexObject)
{
PickerDashboardFragment fragment = new PickerDashboardFragment();
Bundle b = new Bundle();
b.putInt("status", status);
b.putString("name", name);
b.putInt("object", someComplexObject);
fragment.setArguments(bundle);
return fragment;
}
@Provides
public static PickingFragment providesPickingFragment()
{
PickingFragment fragment = new PickingFragment();
return fragment;
}
}
Наличие модуля, предоставляющего int и Strings, вероятно, заставит вас использовать некоторые квалификаторы (такие как Named
) во избежание столкновений
Не вводите фрагменты в свою деятельность с помощью Dagger 2. Почему? Фрагменты имеют жизненный цикл, управляемый ОС Android. Когда вы добавляете фрагмент к действию с помощью транзакции, FragmentManager сохранит ссылку на этот фрагмент. Когда деятельность instanceState
сохраняется, фрагменты, добавленные в FragmentManager, будут сохранены. Когда действие восстанавливается, если вы запрашиваете внедрение без проверки наличия фрагмента в FragmentManager, ваша активность начинает ссылаться на два экземпляра фрагмента и создает утечку памяти.
По этой причине в void onCreate(Bundle savedInstanceState)
В этом случае вам следует проверять наличие сохраненного фрагмента в FragmentManager, а не запрашивать внедрение у Dagger 2. Если фрагмент не сохранен, вы можете создать его экземпляр в этот момент. Это прекрасно, чтобы использовать new
ключевое слово или статические фабрики для этого.
Пример:
MyFragment frag;
void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.content);
frag = fragmentManager.findFragmentByTag(MyFragment.TAG);
if (frag == null) {
frag = MyFragment.instantiate(new Bundle());
}
}
Однако на другом уровне кажется, что вы спрашиваете, как объединить параметры и зависимости. Хорошим решением для этого часто являются фабрики. Скажем, у вас есть кофеварка:
class CoffeeMaker {
private final Kettle kettle;
private final Grinder grinder;
private final BeanFlavour beanFlavour;
CoffeeMaker(Kettle kettle, Grinder grinder, BeanFlavour beanFlavour) {
this.kettle = kettle;
this.grinder = grinder;
this.beanFlavour = beanFlavour;
}
}
BeanFlavour является переменной (темной, жареной и т. Д.) И варьируется, и поэтому он больше похож на параметр, чем на зависимость. Затем вы можете написать CoffeeMakerFactory и внедрить это с помощью Dagger 2:
class CoffeeMakerFactory {
private final Kettle kettle;
private final Grinder grinder;
@Inject
CoffeeMakerFactory(Kettle kettle, Grinder grinder) {
this.kettle = kettle;
this.grinder = grinder;
}
public CoffeeMaker create(BeanFlavour beanFlavour) {
return new CoffeeMaker(kettle, grinder, beanFlavour);
}
}
Фабрики являются стандартным решением для сочетания зависимости и параметров, которые можно увидеть здесь, и их можно даже сгенерировать с помощью инструментов генерации кода, таких как Google Auto.