如何为 Android 功能模块声明 Dagger 活动和片段?

nat*_*rio 6 android dependency-injection kotlin dagger dagger-2

如何为非基本功能模块声明活动和片段?

由于我们只有一个基本功能模块和一个功能模块,我们可以App在功能模块中声明该类并将我们的图加载到那里。这意味着能够使用ContributesAndroidInjectorandroid 的标准 dagger 方法。

现在,添加更多功能模块,我们不能做同样的事情。应用程序类必须留在基础功能模块中,这意味着它不能声明,例如,属于功能的活动。


我的想法:

  • 由于AndroidInjection.inject(this)会在 app 类中寻找活动注入器,所以我们不能使用它。换句话说,没有DaggerAppCompatActivity

  • 所以这个想法是属于功能模块的活动应该创建自己的组件并注入自己。

  • 尽管如此,片段应该可以使用这个@ContributesAndroidInjector东西。对?该AndroidInjection课程将得到父活动喷油器,所以如果我们解决我们的活动,他们将暴露在正确的喷油器,使片段代码可以保留原样。

  • 因此,功能活动必须实现HasFragmentInjector并为片段@Inject添加注释DispatchingAndroidInjector

但是有两件事在这里不起作用。


  1. 特征片段和活动仍然需要@Singleton来自基础特征组件图中的一些带注释的对象,所以我们SpecialFeatureComponent必须以某种方式链接到BaseFeatureComponent.

    似乎这样做的唯一方法是使用dependencies参数:

    @Component(
            dependencies = [BaseFeatureComponent::class],
            modules = [SpecialFeatureModule::class] // @contributes fragment
    )
    interface SpecialFeatureComponent
    
    Run Code Online (Sandbox Code Playgroud)

    SpecialActivity创建这个组件,传递BaseFeatureComponent给它的建造者,并注入本身。

    但是,由于MissingBinding错误,编译失败。特殊功能模块中的某些对象需要@Provide@Singleton来自基础功能组件的带注释的对象,而 dagger 似乎无法正确找到它们。(这些对象不在 中BaseFeatureComponent,而是在其附加模块中)

    如何解决这个问题?

    我已经读到将它们直接暴露在 中BaseFeatureComponent,而不是在其依赖模块中,应该可以解决这个问题,但这不是我们想要做的,因为它们有很多,这将是另一个需要维护的列表。


  1. 照原样, unscopedSpecialFeatureComponent取决于@Singletonscoped BaseFeatureComponent。这是不可能的,所以我们必须添加一个ActivityScope注解。

    @ActivityScope
    @Component(
        dependencies = [BaseFeatureComponent::class],
        modules = [SpecialFeatureModule::class] // @contributes fragment
    )
    interface SpecialFeatureComponent
    
    Run Code Online (Sandbox Code Playgroud)

    现在我们被告知由@ContributesAndroidInjectorfor 片段生成的子组件,无作用域,可能不引用作用域绑定。所以我们在@FragmentScope那里添加了一个注释。

    @Module
    abstract class SpecialFeatureModule {
        @FragmentScope
        @ContributesAndroidInjector
        internal abstract fun specialFragment(): SpecialFragment
    }
    
    Run Code Online (Sandbox Code Playgroud)

    现在我们被告知这些子组件不能引用具有不同作用域的绑定!哪些是@Singleton由基本特征图提供的对象。

如何解决这个问题?