不能用Dagger2提供合格的字符串

我试图在这里跟随样本

我已经成功地使用了AndroidInjector的Dagger2,但现在我正在试验新的DaggerApplicationDaggerAppCompatActivity

我得到的错误:

错误:(5,1)错误:[dagger.android.AndroidInjector.inject(T)] java.lang.String不能提供没有@Inject构造函数或提供@或@ Produces注释的方法。

我不认为新的Daggerclass正在造成这个问题。 如果我删除@DeviceModel @DeviceModel代码编译。

任何建议?

这里代码:

AppComponent.kt

 @Component(modules = arrayOf( AndroidSupportInjectionModule::class, AppModule::class, MainActivitySubComponent.MainActivityModule::class )) interface AppComponent : AndroidInjector { @Component.Builder abstract class Builder : AndroidInjector.Builder() } 

AppModule.kt

 @Module(subcomponents = arrayOf(MainActivitySubComponent::class)) class AppModule { } 

BuildModule.kt

 @Module class BuildModule { @Provides @DeviceModel fun provideModel(): String { return MODEL } } 

DeviceModel.kt

 @Qualifier @Retention(AnnotationRetention.RUNTIME) @MustBeDocumented annotation class DeviceModel 

MainActivitySubComponent.kt

 @Subcomponent(modules = arrayOf(BuildModule::class)) interface MainActivitySubComponent : AndroidInjector { @Subcomponent.Builder abstract class Builder : AndroidInjector.Builder() @Module(subcomponents = arrayOf(MainActivitySubComponent::class)) abstract class MainActivityModule { @Binds @IntoMap @ActivityKey(MainActivity::class) internal abstract fun bind(builder: MainActivitySubComponent.Builder): AndroidInjector.Factory } } 

* MainActivity.kt **

 class MainActivity : DaggerAppCompatActivity() { @Inject @DeviceModel lateinit var model: String override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Log.d(model, model); } } 

App.kt

 class App : DaggerApplication() { override fun applicationInjector(): AndroidInjector { return DaggerAppComponent.builder().create(this) } } 

当用Kotlin对象使用Dagger时,我们必须考虑Kotlin如何在JVM中创建属性。

 @Inject @DeviceModel lateinit var model: String 

有了这样一个属性, Kotlin编译了三个Java元素 :一个私有的后台字段,一个getter和一个setter(由于var而不是val )。 对于您的意图没有进一步的线索,Kotlin将您的DeviceModel注释放在getter上。

解决方案是指定该字段将使用@field:[annotation]

 @Inject @field:DeviceModel lateinit var model: String 

您可能还需要使用@JvmField将Dagger的后台字段公开,这将阻止使用lateinit ,当然,还需要您初始化字符串。

 @Inject @field:DeviceModel @JvmField var model: String 

更新 :我不知道为什么,但在我的测试,该领域是私人的,这就是为什么我建议@JvmField 。 根据Kotlin文件 ,该字段应该与制定者具有相同的可见性。


请注意,一般来说,Kotlin足够聪明,可以将@Target(AnnotationTarget.FIELD)自定义注释应用于后台字段,但这会阻止您在fun providesModel上使用它