Bry*_*yan 20 android dependency-injection kotlin dagger dagger-2
我试图ViewModel通过它们的KClass类型将子类绑定到地图中:
@Module abstract class ViewModelModule {
@Binds @IntoMap @ViewModelKey(MyViewModel::class)
abstract fun bindsMyViewModel(viewModel: MyViewModel): ViewModel
@Binds abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
Run Code Online (Sandbox Code Playgroud)
但我得到Dagger编译错误:
e: ~/Example/app/build/tmp/kapt3/stubs/debug/com/example/app/injection/AppComponent.java:5: error: [dagger.android.AndroidInjector.inject(T)] java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
e:
e: public abstract interface AppComponent {
e: ^
e: java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at
e: com.example.app.ui.ViewModelFactory.<init>(creators)
e: com.example.app.ui.ViewModelFactory is injected at
e: com.example.app.injection.ViewModelModule.bindViewModelFactory(p0)
e: android.arch.lifecycle.ViewModelProvider.Factory is injected at
e: com.example.app.ui.MyFragment.setViewModelFactory(p0)
e: com.example.app.ui.MyFragment is injected at
e: dagger.android.AndroidInjector.inject(arg0)
Run Code Online (Sandbox Code Playgroud)
以上ViewModelModule内容包含在我的中AppModule,这是我的一个模块AppComponent.所以Dagger应该能够提供Map<KClass<out ViewModel>, Provider<ViewModel>>我的要求ViewModelFactory,但我无法弄清楚它为什么会崩溃.
我也尝试将ViewModelKey注释类转换为Java,将a Class作为构造函数参数而不是a KClass.然后修改我ViewModelFactory依赖于a Map<Class<out ViewModel>, Provider<ViewModel>>,但发生了同样的错误.
Kir*_*man 38
KClass在注释中使用时,它实际上被编译为Java Class.但实际问题是java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>>Kotlin编译器生成的通配符.
假设@ViewModelKey被定义为
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
Run Code Online (Sandbox Code Playgroud)
您需要将注射部位定义为
Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
Run Code Online (Sandbox Code Playgroud)
使用@JvmSuppressWildcards将阻止编译器生成通配符.
我实际上并不知道,为什么Dagger编译器不支持通配符.你可以在这里看到类似的问题:Dagger 2:如何注入Map <Class <?扩展Foo>,Provider <?延伸Foo >>
| 归档时间: |
|
| 查看次数: |
2042 次 |
| 最近记录: |