使用Dagger的应用组件构建Android即时应用

22

我目前在尝试使用InstantApps,并希望将dagger包含到我的项目中。

我在设置应用程序AppComponent时遇到了问题。我的应用程序组件包括我的应用程序的所有功能dagger模块。

基本上,我有:

  • 一个基本应用程序模块 包含我的Application类
  • 多个功能 每个活动都有一个dagger模块,其中每个模块都以Base为依赖项。
  • 一个应用程序模块 和即时模块都导入所有功能和基本应用程序模块。

我正在尝试在添加Instant App模块之前弄清楚设置。

来自InstantApps文档和项目示例。似乎需要将Application类放在Base中。从Dagger文档中,要设置dagger:

 DaggerYourAppComponent.create().inject(this);

应该包含在你的应用程序类中。然而,由于AppComponent需要引用所有功能dagger模块,这似乎是不可能的。

我的问题是:

  • 我应该在哪里添加我的AppComponent dagger模块?
  • 我应该将我的应用程序保留在app模块中,而不是Base模块中吗?
  • 有关Dagger与即时应用程序的任何GitHub存储库或文档吗?

谢谢


从这个 InstantApps Compatible Libraries 链接来看,也许 Dagger 还没有得到支持... - Quentin Colle
该链接仅适用于Google库,不适用于第三方。 - TWL
你能检查一下这个网址 https://github.com/ragdroid/instant-app-dagger 吗?或许它能帮到你。 - Prags
2个回答

14
  • Dagger2可很好地支持Instant apps。您可以为每个功能模块创建组件类和相应的Dagger提供者类,以公开每个功能模块的组件类实例。
  • 每个模块组件类都可以声明注入方法,仅包含在该功能模块中的类。
  • 此外,您还可以在基础模块中拥有一个Application组件类,用于应用程序范围内的注入。
  • 应用程序组件类可以在基础模块中包含的Application类中实例化,并通过应用程序类中的静态方法向其他功能模块公开。

以下是使用Dagger2注入Instant apps的示例代码,以更清晰地说明问题。 https://github.com/willowtreeapps/android-instant-apps-demo


谢谢你,@Vishy。我认为你是对的,我需要每个功能一个组件。然而,我仍在寻找一个使用android dagger支持和AndroidInjection.inject(MyActivity.this)以及这里中的AndroidInjector的示例。你有更新样本的计划吗? - Quentin Colle
更具体地说,在 教程 的第 3 步骤中:@Component(modules = {..., YourActivityModule.class}) interface YourApplicationComponent {} 这一步无法完成,因为我的应用程序组件无法访问 ActivityModule,因为它在一个特性模块中。 - Quentin Colle
@QuentinColle 你有找到AndroidInjection.inject(this)的任何示例吗?我在注入功能模块中的活动时卡住了。请给予建议。 - chain

3
我写了一篇关于这个问题的文章,详细介绍了如何使用Dagger2实现模块化架构:《Dagger2 for Modular Architecture》,但以下是简单回答。
你需要以不同的方式使用Dagger2。与其为每个功能模块使用一个module或subcomponent,你需要使用一个带有依赖于基础AppComponent的component。
在一个单独的模块中,我们通常会做如下操作:
@Singleton
@Component(modules = arrayOf(NetworkModule::class, RepositoryModule::class, 
                     SubcomponentModule::class))
interface ApplicationComponent : AndroidInjector<MyApplication> {
  val userRepository: UserRepository
  val apiService: ApiService
}

@Module
object NetworkModule {
  @Provides
  @Singleton
  @JvmStatic
  fun provideApiService(okHttp: OkHttp): ApiService {
    return ApiSerive(okHttp)
  }
 }

但正如你所说,你无法访问可能在另一个模块中或引用其他功能模块中的dagger子组件模块。
你只需要在依赖于ApplicationComponent的特性模块中创建一个新的dagger模块,就像这样:
@Browser
@Component(modules = [(BrowserModule::class)],
      dependencies = [(AppComponent::class)])
interface BrowserComponent : AndroidInjector<AppCompatActivity> {
  @Component.Builder
  abstract class Builder: AndroidInjector.Builder<AppCompatActivity>(){
    /**
    *  explicity declare to Dagger2
    * that this builder will accept an AppComponent instance
    **/
    abstract fun plus(component: AppComponent): Builder
  }
}

相应的特征活动将构建该组件:
class BrowserActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    DaggerBrowserComponent
        .builder()
        /**
         * we have to provide an instance of the AppComponent or
         * any other dependency for this component
         **/
        .plus((application as MyApplication).component)
        .build()
        .inject(this)
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接