我已经简化了我的应用程序以找到问题的根源,这是简化的版本。我正在使用以下配置实现Dagger 2:
AppComponent
@Component(modules = [
AndroidSupportInjectionModule::class,
ActivityBindingModule::class
])
interface AppComponent: AndroidInjector<MyApp> {
@Component.Builder
interface Builder{
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
}
ActivityBindingModule
@Module
abstract class ActivityBindingModule {
@ContributesAndroidInjector
abstract fun mainActivity(): MainActivity
@Module
companion object{
@JvmStatic
@Provides
fun provideString(mainActivity: MainActivity): String{
return "Tent"
}
}
}
MainActivity
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
已经提供了MainActivity
的实例,为什么Dagger仍然对此有所抱怨。
如果没有@Inject构造函数或 @提供注释的方法
编辑(@ yavor)
所有类保持不变,并将 ActivityBindingModule 实现分成两个类。现在您可以看到提供了MainActivity
的实例,而Dagger并没有抱怨它。
ActivityBindingModule
@Module
abstract class ActivityBindingModule {
@ContributesAndroidInjector(modulese [StringProviderModule::class])
abstract fun mainActivity(): MainActivity
}
StringProviderModule
@Module
class StringProviderModule {
@Module
companion object{
@JvmStatic
@Provides
fun provideString(mainActivity: MainActivity): String{
return "Tent"
}
}
}
答案 0 :(得分:1)
您可能忘记了将应用程序注入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"
}
答案 1 :(得分:1)
我不明白的是,ContributesAndroidInjector已经提供了MainActivity的实例,为什么Dagger仍然会抱怨它。
文档中的ContributesAndroidInjector说:
为此方法的返回类型生成一个{@link AndroidInjector}。注入器是通过{@link dagger.Subcomponent}实现的,并且是{@link dagger.Module}组件的子代。
因此它不提供MainActivity。
您为什么真正需要它?我看到您正在将它作为参数传递给函数:
有趣的ProvideString(mainActivity:MainActivity)
但是您真的需要吗?通常,您应该在MainActivity中注入依赖项。 MainActivity应该使用它们。如果两者(MainActivity和字符串)彼此了解,那么首先是-不是一个好的设计,其次是:您即将创建Dagger 2不支持的循环依赖项并引发异常。