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.

Другие вопросы по тегам