首页 > 解决方案 > 为什么@ContributesAndroidInjector 不提供 Android 框架类型

问题描述

我已经简化了我的应用程序以找到问题的根源,这里是简化版本。我正在使用以下配置实现 Dagger 2:

应用组件

@Component(modules = [
    AndroidSupportInjectionModule::class,
    ActivityBindingModule::class
])
interface AppComponent: AndroidInjector<MyApp> {
    @Component.Builder
    interface Builder{
        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }
}

活动绑定模块

@Module
abstract class ActivityBindingModule {
    @ContributesAndroidInjector
    abstract fun mainActivity(): MainActivity

    @Module
    companion object{
        @JvmStatic
        @Provides
        fun provideString(mainActivity: MainActivity): String{
            return "Tent"
        }
    }
}

主要活动

class MainActivity : DaggerAppCompatActivity() {

    @Inject
    lateinit var string: String

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        println("meco simplest ${string}")
    }
}

当我运行应用程序时,出现以下错误。我不明白的是ContributesAndroidInjector,它已经提供了MainActivityDagger 仍然抱怨它的原因。

如果没有 @Inject 构造函数或 @Provides 注释方法,则无法提供 MainActivity

编辑@yavor

保持所有类不变,并将ActivityBindingModule实现分成两个类。现在您可以看到MainActivity提供了 的实例,并且 Dagger 并没有抱怨它。 活动绑定模块

@Module
abstract class ActivityBindingModule {
    @ContributesAndroidInjector(modulese [StringProviderModule::class])
    abstract fun mainActivity(): MainActivity
}

字符串提供者模块

@Module
class StringProviderModule {
    @Module
    companion object{
        @JvmStatic
        @Provides
        fun provideString(mainActivity: MainActivity): String{
            return "Tent"
        }
    }
}

标签: dagger-2dagger

解决方案


您可能忘记将应用程序注入MyApp. 你应该有这样的东西(你可能需要稍微修改一下以适应你的AppComponent

DaggerAppComponent.builder()
    .application(this)
    .build()
    .inject(this)

此外,Dagger 实际上是MainActivity通过您的@ContributesAndroidInjector注释方法提供您的,但这不是您要注入的。

你正在注入一个string所以 Dagger 正在使用你的provideString方法。由于这个方法需要一个MainActivity实例才能工作,所以 Dagger 正在寻找这样一个用@Provides. 你没有,Dagger 不会查看你的@ContributesAndroidInjector方法,因为它没有任何理由这样做。

如果你想让它工作,你实际上必须provideString在一个单独的模块中定义你的方法并将它安装在你的@ContributesAndroidInjector

@Module
abstract class ActivityBindingModule {
    @ContributesAndroidInjector(modules = [StringModule::class])
    abstract fun mainActivity(): MainActivity
}

@Module
class StringModule {

    @JvmStatic
    @Provides
    fun provideString(mainActivity: MainActivity): String = "Hehe"
}

推荐阅读