ViewModel 中的 Kotlin Dagger 字段注入引发 Dagger/Binding 异常
Posted
技术标签:
【中文标题】ViewModel 中的 Kotlin Dagger 字段注入引发 Dagger/Binding 异常【英文标题】:Kotliin Dagger Field Injection in ViewModel Throws Dagger/Binding Exception 【发布时间】:2019-11-28 21:20:05 【问题描述】:我已关注this tutorial,以便在我的视图模型中进行 DI。但我目前被卡住了。
我为我的视图模型创建了一个 ViewModelFactory,如下所示:
class HomeViewModelFactory @Inject constructor(
private val creators: Map<Class<out ViewModel>,
Provider<ViewModel>>
): ViewModelProvider.Factory
override fun <T : ViewModel?> create(modelClass: Class<T>): T
return creators[modelClass]?.get() as T
后跟一个 ViewModel:
class HomeViewModel @Inject constructor(private val songsRepository: SongsRepository): ViewModel()
对于 DI,我创建了两个组件。一个是我的主应用组件,另一个是依赖于主应用的组件。
@Singleton
@Component(modules = [AppModule::class])
public interface AppComponent
fun songRepository(): SongsRepository
fun libraryManager(): LibraryManager
fun inject(mainActivity: MainActivity)
@Module
public class AppModule(val application: Application)
@Provides @Singleton
fun providesApplication(): Application
return application
@Provides @Singleton
fun providesLibraryManager(): LibraryManager
return LibraryManager(application)
@Provides @Singleton
fun providesSongRepository(libraryManager: LibraryManager): SongsRepository
return SongsRepository(libraryManager)
而我的 ViewModelModule 如下:
@Module
public class ViewModelModule
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
@AppScope
@Provides
fun providesHomeViewModelFactory(providerMap: Map<Class<out ViewModel>, Provider<ViewModel>>): HomeViewModelFactory
return HomeViewModelFactory(providerMap)
@AppScope
@IntoMap
@Provides
@ViewModelKey(HomeViewModel::class)
fun providesHomeViewModel(songsRepository: SongsRepository): HomeViewModel
return HomeViewModel(songsRepository)
@AppScope
@Component(modules = [ViewModelModule::class], dependencies = [AppComponent::class])
public interface ViewModelComponent
fun homeViewModelFactory(): HomeViewModelFactory
fun homeViewModel(): HomeViewModel
fun inject(homeFragment: HomeFragment)
我得到的错误是:
错误:[Dagger/MissingBinding] java.util.Map,?延伸 javax.inject.Provider> 不能 在没有 @Provides 注释的方法的情况下提供。
我真的不知道为什么会发生这种情况,因为我所有的类都有 @Inject 构造函数。 Dagger 的文档也没有帮助我。如果您能就此问题给我建议,我将不胜感激。
【问题讨论】:
【参考方案1】:错误信息表示以下代码错误:
fun providesHomeViewModelFactory(providerMap: Map<Class<out ViewModel>, Provider<ViewModel>>): HomeViewModelFactory
return HomeViewModelFactory(providerMap)
应该是
fun providesHomeViewModelFactory(providerMap: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>): HomeViewModelFactory
return HomeViewModelFactory(providerMap)
这是因为Map
接口的签名是Map<K, out V>
,这意味着Map<..., Provider<ViewModel>>
将被编译成Map<..., ? extends Provider<ViewModel>>
Java代码,所以你问匕首是后者,但它只有前者对象图,然后编译器会抛出错误。
【讨论】:
改成之后我仍然收到此错误。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 com.application.mvvmmusicplayer.ui.main.home.viewmodel.HomeViewModelFactory homeViewModelFactory();
正如错误所说,您没有提供ViewModel
类,providesHomeViewModel
函数应该返回ViewModel
而不是HomeViewModel
。以上是关于ViewModel 中的 Kotlin Dagger 字段注入引发 Dagger/Binding 异常的主要内容,如果未能解决你的问题,请参考以下文章
ViewModel 中的 Kotlin Dagger 字段注入引发 Dagger/Binding 异常
纯kotlin+ViewModel+LiveData+协程MVVM
Android : Kotlin : MVVM : 为啥 viewModel.onButtonClicked() 会导致应用程序崩溃?
如何将editText值传递给viewModel和Livedata(Kotlin)
Android - ViewModel、LiveData、Room 和 Retrofit 以及协程放在 kotlin 中