Android Dagger-2如何为方法参数提供依赖

时间:2017-07-10 12:06:47

标签: android dagger-2 dagger

我有一个模块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类

@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)提供依赖关系的最佳和最简单的方法,即status,name和someComplexObject。

最好的问候

2 个答案:

答案 0 :(得分: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和字符串的模块可能会让你使用一些限定符(例如Named)以避免冲突

答案 1 :(得分:2)

不要使用Dagger 2将片段注入您的活动中。为什么?片段具有由Android OS控制的生命周期。使用事务向活动添加片段时,FragmentManager将保留对片段的引用。保存活动instanceState后,将保存添加到FragmentManager的碎片。恢复活动时,如果您在不检查FragmentManager中是否存在Fragment的情况下请求注入,则Activity会开始引用Fragment的两个实例并创建内存泄漏。

因此,在void onCreate(Bundle savedInstanceState)方法中,您应检查FragmentManager中是否存在保留的Fragment,而不是请求Dagger 2注入。如果未保留Fragment,则可以在该点实例化它。完全可以使用new关键字或静态工厂。

示例:

MyFragment frag;

void onCreate(Bundle savedInstanceState) {
     setContentView(R.layout.content);
     frag = fragmentManager.findFragmentByTag(MyFragment.TAG);
     if (frag == null) {
         frag = MyFragment.instantiate(new Bundle());
     }
}

但是,在另一个层面上,您似乎在询问如何组合参数和依赖项。对于这些的一个很好的解决方案通常是工厂。假设你有一个CoffeeMaker:

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);
     }
 }

工厂是依赖项和参数see here组合的标准解决方案,甚至可以使用Google Auto等代码生成工具生成它们。