由于我们只有一个基本要素模块和一个要素模块,因此可以在要素模块中声明App
类,然后将图形加载到那里。这意味着能够为Android使用ContributesAndroidInjector
和标准匕首方法。
现在,添加更多功能模块,我们不能做同样的事情。应用程序类必须保留在基本功能模块中,这意味着它不能声明例如属于功能的活动。
我的想法:
由于AndroidInjection.inject(this)
将在应用程序类中查找活动注入器,因此无法使用它。换句话说,没有DaggerAppCompatActivity
。
因此,想法是,属于功能模块的活动应该创建自己的组件并自行注入。
不过,片段应该可以使用@ContributesAndroidInjector
东西。对吗? AndroidInjection
类将从父活动中获取注入器,因此,如果我们修复活动,则它们将公开正确的注入器,以便可以按原样保留片段代码。
由于这个原因,要素活动必须实现HasFragmentInjector
并在片段上标注@Inject
并附加DispatchingAndroidInjector
。
但是这里有两件事不起作用。
功能片段和活动仍需要基础特征组件图中的一些@Singleton
带注释的对象,因此我们的SpecialFeatureComponent
必须以某种方式链接到BaseFeatureComponent
。 / strong>
似乎唯一的方法是使用dependencies
参数:
@Component(
dependencies = [BaseFeatureComponent::class],
modules = [SpecialFeatureModule::class] // @contributes fragment
)
interface SpecialFeatureComponent
SpecialActivity
创建此组件,将BaseFeatureComponent
传递给其生成器,然后自我注入。
但是,由于MissingBinding
错误导致编译失败。特殊功能模块中的某些对象需要基础特征组件中的@Provide
,@Singleton
带注释的对象,而匕首似乎无法正确找到它们。 (这些对象不在BaseFeatureComponent
中,而是在其连接的模块中)
我已经读到,直接在BaseFeatureComponent
中而不是在其依赖项模块中公开它们应该可以解决此问题,但这不是我们想做的事情,因为它们很多而且还没有另一个要维护的列表。
按原样,不受范围限制的SpecialFeatureComponent
取决于@Singleton
范围内的BaseFeatureComponent
。这是不可能的,所以我们必须添加一个ActivityScope
注释。
@ActivityScope
@Component(
dependencies = [BaseFeatureComponent::class],
modules = [SpecialFeatureModule::class] // @contributes fragment
)
interface SpecialFeatureComponent
现在,我们被告知@ContributesAndroidInjector
为未生成片段的片段生成的子组件可能未引用作用域绑定。因此,我们在此处添加了@FragmentScope
注释。
@Module
abstract class SpecialFeatureModule {
@FragmentScope
@ContributesAndroidInjector
internal abstract fun specialFragment(): SpecialFragment
}
现在,我们被告知这些子组件可能无法引用范围不同的绑定!基本要素图提供的@Singleton
个对象。