安卓匕首-如何从其他模块注入



我的应用程序中有多个模块,每个模块都有自己的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()构造函数,因此没有其他构造函数参数的空间。当您看到带有@ContributesAndroidInjectorabstract 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注释的方法也将被调用。这是方法注入,与现场注入员注入对于所有构造函数初始化后达格可以做的事情。

最新更新