不能用Dagger2提供合格的字符串
我试图在这里跟随样本
我已经成功地使用了AndroidInjector的Dagger2,但现在我正在试验新的DaggerApplication
和DaggerAppCompatActivity
。
我得到的错误:
错误:(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
上使用它