Java 如何使用一个ViewModelFactory为ViewModels提供Dagger
如何实现一个Java 如何使用一个ViewModelFactory为ViewModels提供Dagger,java,android,kotlin,viewmodel,dagger,Java,Android,Kotlin,Viewmodel,Dagger,如何实现一个ViewModelFactory来提供我的项目ViewModels及其对整个项目的依赖关系?嗯,有一个名为,但它不是教程,它是一个项目。你们应该知道安卓的匕首。或者,您可以检查以下代码: @Singleton class DaggerViewModelFactory @Inject constructor( private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provid
ViewModelFactory
来提供我的项目ViewModels
及其对整个项目的依赖关系?嗯,有一个名为,但它不是教程,它是一个项目。你们应该知道安卓的匕首。或者,您可以检查以下代码:
@Singleton
class DaggerViewModelFactory @Inject constructor(
private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
val creator = creators[modelClass] ?: creators.entries.firstOrNull {
modelClass.isAssignableFrom(it.key)
}?.value ?: throw IllegalArgumentException("unknown model class $modelClass")
try {
@Suppress("UNCHECKED_CAST")
return creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
现在是有趣的部分:
@Suppress("unused")
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(MyViewModel::class)
abstract fun bindsMyViewModel(viewModel: MyViewModel): ViewModel
@Binds
abstract fun bindsViewModelFactory(factory: DaggerViewModelFactory): ViewModelProvider.Factory
}
由于dagger支持多重绑定,您可以根据需要自由绑定视图模型
ViewModelKey:
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
明确您在评论中的要求。首先,不需要特别了解DaggerViewModelFactory
内部发生了什么,尽管我不建议用这种方式学习,因为我非常喜欢“总是知道发生了什么”。仅供参考,DaggerViewModelFactory
只是一个类,它接受一个Map
,每个扩展ViewModel
的类作为键,类依赖项作为值。使用Provider
时,Dagger知道如何查找这些依赖项,但在调用Provider.get()
之前,Dagger不会将它们提供给您。把它看作是一个懒惰的初始化
现在检查modelClass.isAssignableFrom(it.key)
。它只是检查该类是否真的扩展了ViewModel
至于你的第二个问题,理解第一部分很重要。由于
Dagger
支持多绑定,这意味着您可以使用映射提供依赖项。例如,一个地图
基本上会告诉dagger它给了我HomeViewModel
的依赖关系。Dagger会说:如何知道哪些是HomeViewModel
依赖项?您回答:我已经为此定义了一个键,它是HomeViewModel
类本身。因此,您只需创建一个注释,将其与@Binds
和@IntoMap
结合,然后在后台Dagger将只执行一个映射。put(HomeViewModel::class,and Dependencies)
别担心,我会在帖子上额外添加一些探索。完成后,请再次检查谢谢!清晰易懂!很高兴我帮了忙:)当你是初学者时,这是一种高级的。我有一篇关于dagger的文章,如果你想学习基本知识:
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
class MyViewModel @Inject constructor(
private val dependency: YourDependency
) : ViewModel() {}