使用dagger2进行依赖注入时,我可以注入超类吗?

Chr*_*Zou 44 java android dependency-injection dagger dagger-2

我在我的android应用程序中使用Dagger2 for DI.我发现我必须为每个使用@Inject字段的类编写inject方法.有没有办法我可以注入父类,这样我就不必在每个子类上调用注入?以活动为例.我有一个BaseActivity每个活动都延伸出来的.有没有办法可以在组件中为BaseActivity创建一个注入方法,只需在BaseActivity的onCreate中调用注入,子活动中的@inject字段会自动注入?

Gor*_*dak 41

我遇到了同样的情况.在所有活动中缓解来自公共组件的注入的一种方法如下:

1)扩展Application类,以便能够创建公共组件并保持对它的引用.

public class ApplicationDagger extends Application {

    private ApplicationComponent component;

    @Override
    public void onCreate(){
        super.onCreate();
        component = DaggerApplicationComponent.builder().applicationModule(new ApplicationModule(this)).build();
    }

    public ApplicationComponent getComponent(){
            return component;
    }
}
Run Code Online (Sandbox Code Playgroud)

2)创建一个抽象的DaggerActivity,它从Application获取公共组件并调用抽象方法injectActivity,将组件作为参数.像这样:

public abstract class DaggerActivity extends Activity {

    @Override
    public void onCreate(Bundle saved){
        super.onCreate(saved);
        ApplicationComponent component = ((ApplicationDagger) getApplication()).getComponent();
        injectActivity(component);
    }

    public abstract void injectActivity(ApplicationComponent component);
}
Run Code Online (Sandbox Code Playgroud)

3)最后,你必须实际注入每个Activity扩展DaggerActivity.但是现在可以用更少的努力来完成,因为你必须实现该abstract方法,否则你将得到编译错误.开始了:

public class FirstActivity extends DaggerActivity {

    @Inject
    ClassToInject object;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //initialize your Activity
    }

    @Override
    public void injectActivity(ApplicationComponent component) {
        component.inject(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您仍然必须在Component中明确声明每个Activity.

更新:将@ActivityScope对象注入碎片

在某些时候,我需要使用自定义范围将对象绑定到 Activity生命周期.我决定延长这篇文章,因为它可能会帮助一些人.

假设你有一个@ModuleActivityModule和一个@Subcomponent接口ActivityComponent.

你需要修改DaggerActivity.该Activities扩展DaggerActivity需要实现新的方法(签字的变化).

public abstract class ActivityDagger extends AppCompatActivity {

    ActivityComponent component;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        component = ((ApplicationDagger) getApplication()).getComponent().plus(new ActivityModule(this));
        injectActivity(component);
        super.onCreate(savedInstanceState);
    }

    ActivityComponent getComponent() {
        return component;
    }

    public abstract void injectActivity(ActivityComponent component);
}
Run Code Online (Sandbox Code Playgroud)

然后,可以像这样创建一个类FragmentDagger扩展Fragment:

public abstract class FragmentDagger extends Fragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityDagger activityDagger = (ActivityDagger) getActivity();
        ActivityComponent component = activityDagger.getComponent();
        injectFragment(component);
    }

    public abstract void injectFragment(ActivityComponent component);

}
Run Code Online (Sandbox Code Playgroud)

至于Activities,Fragments扩展FragmentDagger只有一种方法可以实现:

public abstract void injectFragment(ActivityComponent component);
Run Code Online (Sandbox Code Playgroud)

您应该可以Fragments在任何地方重复使用.请注意,应在组件实例化后调用方法super.onCreated()in ActivityDagger.否则,你会得到NullPointerException异常时的Activity状态重新创建,因为该方法super.onCreate()Fragment将被调用.


Kir*_*nov 29

它现在无法完成.Gregory Kick的解释(来自这里):

以下是成员注入方法的工作原理:

  1. 您可以为@Inject在其类层次结构中具有任何位置的任何类型创建成员注入方法.如果没有,您将收到错误.
  2. @Inject将注入整个类型层次结构中的所有ed成员:参数类型和所有超类型.
  3. @Inject对于参数类型的子类型,不会编辑任何成员.

此处此处讨论了此问题,请按以下步骤进行更新.但它不太可能很快改变,因为Dagger 2 即将发布.