使用新的(在2.10中)dagger.android类,我试图使用依赖于其他模块的Subcomponent注入(inject)事物,因此,有了一个带有针对这些模块的setter的Builder。 https://google.github.io/dagger/android.html上的文档对此进行了描述,但是尚不清楚如何实际编写和/或调用这些 setter 。

从以上链接引用:



在我看来,为了能够调用Builder的设置者,我需要进入某个地方并确保Builder具有所有必要的数据?我看到的问题是,在运行时,当AndroidInjector调用为我的子组件生成的生成器时,我得到了IllegalStateException: MODULE must be set

有问题的子组件实际上是一个片段,而不是一个 Activity ,但是我不确定那应该很重要。有关如何执行此操作的任何想法?

最佳答案

简而言之,您应该在Builder上使用override the call to seedInstance (这是一个抽象类,而不是一个接口(interface))来提供所需的其他模块。

编辑:在执行此操作之前,请检查并确保确实需要通过该模块。与Damon added in a separate answer一样,如果您要为Android类创建特定的模块,则可以依靠该类的自动注入(inject)在那时将配置或实例从图形中拉出。如果仅从您的Module中消除构造函数参数会更容易,那就支持他的方法,因为这样可以避免不必要的实例和虚拟方法调用,因此还可以提供更好的性能。

首先,在30秒内完成 dagger.android:而不是让每个Activity或Fragment都知道其父级,Activity(或Fragment)调用AndroidInjection.inject(this),后者检查Application的HasActivityInjector(或父片段,activity和application的HasFragmentInjector)。 。这个想法是,您将绑定(bind)贡献给创建了multibindings的Map<Class, AndroidInjector.Factory>,其中贡献的绑定(bind)几乎总是您编写的用于构建对象特定子组件的子组件构建器。

正如您从AndroidInjection.inject(this)AndroidInjector.Factory.create(T instance)所知道的那样,您没有太多机会将特定于 Activity 或特定于片段的详细信息传递给Builder。相反,其想法是您的子组件构建器将覆盖seedInstance实现。就像在seedInstance的文档中一样:



看起来像这样:

@Subcomponent(modules = {OneModule.class, TwoModule.class})
public interface YourActivitySubcomponent extends AndroidInjector<YourActivity> {

  // inject(YourActivity) is inherited from AndroidInjector<YourActivity>

  @Builder
  public abstract class Builder extends AndroidInjector.Builder<YourActivity> {
    // Here are your required module builders:
    abstract Builder oneModule(OneModule module);
    abstract Builder twoModule(TwoModule module);

    // By overriding seedInstance, you don't let Dagger provide its
    // normal @BindsInstance implementation, but you can supply the
    // instance to modules or call your own BindsInstance:
    @Override public void seedInstance(YourActivity activity) {
      oneModule(new OneModule(activity));
      twoModule(new TwoModule(activity.getTwoModuleParameter()));
    }
  }
}

这里的假设是您需要等待模块的activity实例。如果没有,那么在绑定(bind)子组件时,您还可以选择调用那些:
@Provides @IntoMap @ActivityKey(YourActivity.class)
AndroidInjector.Factory bindInjector(YourActivitySubcomponent.Builder builder) {
  return builder
      .oneModule(new OneModule(...))
      .twoModule(new TwoModule(...));
}

...但是如果您能做到这一点,那么您可以通过覆盖那些模块,实现一个可以提供Module的构造函数参数的零参数构造函数,并让Dagger像创建任何对象一样创建这些参数,来更轻松地处理这些绑定(bind)。具有公共(public)零参数构造函数的模块。

关于android - Dagger 2.10 Android子组件和构建器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43371863/

10-10 22:32