使用Dagger2和ViewModelProvider.Factory注入ViewModel类可以在Kotlin 1.3.21上正常工作,但是当我切换到1.3.30时无法编译。 谁能发现我(毫无疑问)做错了什么?
我浏览了类似的问题报告,但是还没有人看到我在Kotlin版本之间看到的结果差异。
可通过以下网址访问项目:https://github.com/alteredworlds/posts
分支“ master”可以正常构建,而“ upgradeKotlinBuildFails”则不能。唯一的变化是将Kotlin从1.3.21移至1.3.30。
代码摘要:
@Singleton
class ViewModelFactory @Inject constructor(
private val viewModels: MutableMap<Class<out ViewModel>,
@JvmSuppressWildcards Provider<ViewModel>>) :
ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
}
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
@Module
abstract class ViewModelModule {
@Binds
internal abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
@Binds
@IntoMap
@ViewModelKey(PostsActivityViewModel::class)
internal abstract fun bindPostsActivityViewModel(viewModel: PostsActivityViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(PostDetailActivityViewModel::class)
internal abstract fun bindsPostDetailActivityViewModel(viewModel: PostDetailActivityViewModel): ViewModel
}
@Singleton
@Component(modules = arrayOf(
AndroidSupportInjectionModule::class,
RepoModule::class,
ActivityBuilderModule::class,
ViewModelModule::class)
)
interface AppComponent {
fun inject(application: PostsApplication)
@Component.Builder interface Builder {
@BindsInstance fun application(application: Application): Builder
fun build(): AppComponent
}
}
使用Kotlin 1.3.21构建并运行代码。使用Kotlin 1.3.30,构建结果如下:
Posts/app/build/tmp/kapt3/stubs/debug/com/example/twcgilbert/postsapp/app/di/AppComponent.java:11: error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
public abstract interface AppComponent {
^
java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
com.example.twcgilbert.postsapp.common.di.ViewModelFactory(viewModels)
com.example.twcgilbert.postsapp.common.di.ViewModelFactory is injected at
com.example.twcgilbert.postsapp.ui.di.ViewModelModule.bindViewModelFactory$app_debug(factory)
androidx.lifecycle.ViewModelProvider.Factory is injected at
com.example.twcgilbert.postsapp.ui.posts.PostsActivity.viewModelFactory
com.example.twcgilbert.postsapp.ui.posts.PostsActivity is injected at
dagger.android.AndroidInjector.inject(T) [com.example.twcgilbert.postsapp.app.di.AppComponent → com.example.twcgilbert.postsapp.app.di.ActivityBuilderModule_BindPostsActivity.PostsActivitySubcomponent]
The following other entry points also depend on it:
dagger.android.AndroidInjector.inject(T) [com.example.twcgilbert.postsapp.app.di.AppComponent → com.example.twcgilbert.postsapp.app.di.ActivityBuilderModule_BindPostDetailActivity.PostDetailActivitySubcomponent]