作者:赵博钧石博 | 来源:互联网 | 2023-02-06 19:09
使用新的(在2.10中)dagger.android类,我正在尝试使用依赖于其他模块的子组件来注入事物,因此,它有一个带有这些模块的setter的Builder.https://google.github.io/dagger/android.html上的文档描述了这一点,但不清楚如何实际编写和/或调用这些setter.
引用上面的链接:
AndroidInjection.inject()从Application获取DispatchingAndroidInjector并将您的活动传递给inject(Activity).DispatchingAndroidInjector为您的活动类(即YourActivitySubcomponent.Builder)查找AndroidInjector.Factory,创建AndroidInjector(即YourActivitySubcomponent),并将您的活动传递给inject(YourActivity).
在我看来,为了能够为Builder调用setter,我需要进入某处并确保Builder具有所有必要的数据?我看到的问题是,在运行时,我得到一个IllegalStateException: MODULE must be set
,当我的子组件生成的构建器被AndroidInjector调用时.
有问题的子组件实际上是一个片段,而不是一个活动,但我不确定这是否重要.关于如何做到这一点的任何想法?
1> Jeff Bowman ..:
简而言之,您应该覆盖seedInstance
对Builder(这是一个抽象类而不是接口)的调用,以提供您需要的其他模块.
编辑:在此之前,检查并确保您确实需要通过该模块.正如Damon在一个单独的答案中添加的那样,如果您为Android类制作了一个特定的模块,那么您可以依靠该类的自动注入来将该配置或实例拉出图表.如果从模块中消除构造函数参数更容易,那么也可以使用他的方法,这也可以提供更好的性能,因为它们可以避免不必要的实例和虚方法调用.
首先,dagger.android在30秒内:而不是让每个Activity或Fragment知道它的父,Activity(或Fragment)调用AndroidInjection.inject(this)
,它检查Application HasActivityInjector
(或父片段,活动和应用程序HasFragmentInjector
).我们的想法是您为多绑定创建Map
提供绑定,其中提供的绑定几乎总是您编写的构建特定于对象的子组件的子组件构建器.
正如您所说,AndroidInjection.inject(this)
并且AndroidInjector.Factory.create(T instance)
,您没有很多机会将特定于Activity或Fragment的详细信息传递给Builder.相反,我们的想法是您的子组件构建器会覆盖seedInstance
实现.如在以下文档中seedInstance
:
提供instance
用于构建的绑定图AndroidInjector
.默认情况下,它用作BindsInstance
方法,但可以重写它以提供需要引用活动的任何模块.
这应该是将传递给的相同实例inject(Object)
.
看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @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()));
}
}
}
< /youractivity >< /youractivity >< /youractivity >
|
这里的假设是您需要等待activity
模块的实例.如果没有,那么您还可以选择在绑定子组件时调用它们:
1 2 3 4 5 6 | @Provides @IntoMap @ActivityKey(YourActivity.class)
AndroidInjector.Factory bindInjector(YourActivitySubcomponent.Builder builder) {
return builder
.oneModule(new OneModule(...))
.twoModule(new TwoModule(...));
}
|
...但是如果你能做到这一点,那么你可以通过覆盖这些模块,实现一个可以提供Module的构造函数参数的零参数构造函数,并让Dagger创建它们,因为它可以更轻松地处理这些绑定.具有公共零arg构造函数的模块.
这完全奏效了!虽然文档中的任何地方都没有提到它,但是对于使用dagger 2 +的新用户而言,文档很难理解.