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

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


答案 1

我遇到了同样的情况。从所有活动中的公共组件注入一点的一种方法是:

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

2)创建一个抽象的DaggerActivity,它从应用程序获取公共组件并调用一个抽象方法,给出该组件作为参数。喜欢这个: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);
}

3)最后,您必须实际注入每个扩展。但是现在只需较少的工作量即可完成此操作,因为您必须实现该方法,否则将出现编译错误。来吧:ActivityDaggerActivityabstract

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

当然,您仍然必须在组件中显式声明每个活动。

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

在某些时候,我需要使用自定义作用域将对象绑定到生命周期。我决定扩展这篇文章,因为它可能会帮助一些人。Activity

假设您有一个@Module类和一个@Subcomponent接口。ActivityModuleActivityComponent

您需要修改 .扩展需要实现新方法(更改签名)。DaggerActivityActivitiesDaggerActivity

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

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

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

}

至于 ,扩展只有一个方法可以实现:ActivitiesFragmentsFragmentDagger

public abstract void injectFragment(ActivityComponent component);

您应该能够在任何需要的地方重复使用。请注意,应在组件实例化之后调用 中的方法。否则,当重新创建状态时,您将获得 NullPointerException,因为将调用 的方法。Fragmentssuper.onCreated()ActivityDaggerActivitysuper.onCreate()Fragment


答案 2

现在无法做到这一点。Gregory Kick的解释(从这里开始):

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

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

这里这里讨论了这个问题,请跟进这些更新。但它不太可能很快改变,因为Dagger 2即将发布


推荐