我的应用程序中有多个模块,每个模块都有自己的UI注入模块。
现在,我想拥有"饲料";具有来自其他模块的一些片段的片段。所以我试着用FragmentContainerView来做。我想注入在其他模块上定义的片段。我正在努力";包括";我的另一个片段,所以我可以导航到这个片段,但如果我试图注入它,我会得到以下错误:
错误:没有@Inject构造函数或@Providers带注释的方法,就无法提供[Dager/MissingBinding]DotsFragment。此类型支持成员注入,但不能隐式提供。
知道我该怎么做吗?
主页模块:
@Module(
includes = [
DotsModule::class
]
)
abstract class HomeModule {
}
DotsModule:
@Module
abstract class DotsModule {
@FragmentScoped
@ContributesAndroidInjector
abstract fun contributeDotsFragment(): DotsFragment
}
主页片段:
@Inject
lateinit var dotsFragment: DotsFragment
只需按照文档中的描述将Fragment推入容器中,就不用担心注入了。您甚至不需要从HomeModule中明确包含DotsModule,尽管您可以选择保留它,特别是如果HomeModule在不同的活动中。DotsFragment将在onAttach
中注入自身。
与大多数使用Dagger注入的类不同,Fragments不能注入到它们的构造函数中:Android只会调用零arg或一个argFragment()
构造函数,因此没有其他构造函数参数的空间。当您看到带有@ContributesAndroidInjector
的abstract fun contributeDotsFragment()
函数时,DotsFragment在要构建或提供的图上并不可用。相反,Dagger做了一些魔术1,允许片段在onAttach
中调用AndroidSupportInjection.inject(this)
后填充其@Inject
标记的字段2。如果从中继承,这可能会发生在DaggerFragment中。您的Fragment必须假设任何标记为@Inject
的内容都是null
,直到附加Fragment为止。
因此,如果您需要DotsFragment的实例,您可以直接调用DotsFragment()
或委派给FragmentManager的FragmentFactory(可能只调用DotsFragment()
(。您还可以对FragmentTransaction.replace(...)
使用重载,该重载采用Class<Fragment>
而不是Fragment实例。
Fragment稍后将在onAttach
中注入自己,就像Android自己调用构造函数一样。如果在此之前与Fragment交互,请小心,因为它的@Inject
注释字段尚未填充。如果您需要使用Dagger提供的实例与Fragment进行交互,那么最好创建一个Bundle,Fragment可以使用该Bundle在onCreate
中初始化自己。
1:在幕后,dagger.android创建了一个代码生成的子组件实例,可能称为DotsModule_BindDotsFragment.DotsFragmentSubcomponent
,并将该子组件注册为Map中的AndroidInjector.Factory<DotsFragment>
。生成的子组件接收在@ContributesAndroidInjector
注释上设置的所有modules
以及在abstract fun
上设置的全部作用域注释。在onAttach
(您的或DaggerFragment的(中,对AndroidSupportInjection.inject(this)
的调用从该Map中读取,找到Injector/Subcomponent,创建一个实例,并使用该实例将Fragment及其自己的一组@FragmentScope
实例注入。
2@Inject
注释的方法也将被调用。这是方法注入,与现场注入员注入对于所有构造函数初始化后达格可以做的事情。