无法使用Dagger2提供合格的字符串

时间:2018-01-12 17:19:24

标签: android kotlin dagger

我正在尝试关注示例here

我已经成功使用了Dagger2和AndroidInjector,但现在我正在试验新的this.dataSource = Observable.create((observer: any) => { // Runs on every search observer.next(this.typeAheadResult); }).mergeMap((token: string) => { return this.httpClient.get<string[]>(`${this.typeAheadUrl}?q=${token}`).map(r => r); }); DaggerApplication

我收到错误:

  

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

我不认为新的Dagger类导致了这个问题。 如果我删除 BuildModule.kt 中的DaggerAppCompatActivity,代码就会编译。

有什么建议吗?

这里是代码:

AppComponent.kt

@DeviceModel

AppModule.kt

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

BuildModule.kt

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

}

DeviceModel.kt

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

MainActivitySubComponent.kt

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

* MainActivity.kt **

@Subcomponent(modules = arrayOf(BuildModule::class))
interface MainActivitySubComponent : AndroidInjector<MainActivity> {

    @Subcomponent.Builder
    abstract class Builder : AndroidInjector.Builder<MainActivity>()

    @Module(subcomponents = arrayOf(MainActivitySubComponent::class))
    abstract class MainActivityModule {
        @Binds
        @IntoMap
        @ActivityKey(MainActivity::class)
        internal abstract fun bind(builder: MainActivitySubComponent.Builder): AndroidInjector.Factory<out Activity>
    }
}

App.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);
    }
}

1 个答案:

答案 0 :(得分:1)

将Dagger与Kotlin对象一起使用时,我们必须考虑Kotlin如何在JVM中实际创建属性。

@Inject
@DeviceModel
lateinit var model: String

使用这样的属性Kotlin compiles three Java elements:私有支持字段,getter和setter(由于var而不是val)。由于没有关于你的意图的进一步线索,Kotlin将你的DeviceModel注释放在吸气剂上。

解决方案是指定要使用@field:[annotation]注释该字段。

@Inject
@field:DeviceModel
lateinit var model: String

您可能还需要使用@JvmField为Dagger公开支持字段,这将排除使用lateinit,当然,还需要您初始化字符串。

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

更新:我不确定原因,但在我的测试中,该字段是私有的,这就是我建议@JvmField的原因。根据{{​​3}},应该创建与setter具有相同可见性的字段。

请注意,一般情况下,Kotlin足够聪明,可以将@Target(AnnotationTarget.FIELD)的自定义注释应用于支持字段,但这会阻止您在fun providesModel

上使用它