Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。
想改善这个问题吗?更新问题,以便将其作为on-topic用于堆栈溢出。
去年关闭。
Improve this question
如何实现
这部分将为整个应用程序创建一个“通用” View 模型。以这种方式,创建了
现在有趣的部分:
由于 Dagger 支持多重绑定(bind),因此您可以根据需要随意绑定(bind)
ViewModelKey:
您基本上是将值放在哈希图中。这些值是您的
打建立!完成后,您只需在片段中插入一个
明确您对评论的要求。首先,虽然我不建议学习这种方式,但我并没有特别的需要知道
现在检查
至于第二个问题,了解第一部分很重要。由于
想改善这个问题吗?更新问题,以便将其作为on-topic用于堆栈溢出。
去年关闭。
Improve this question
如何实现
ViewModelFactory
以提供我的项目ViewModels
及其整个项目的依赖关系? 最佳答案
嗯,有一个叫做GithubBrowser的文件,但这不是教程,而是一个项目。你应该知道 Dagger 为Android做到这一点。或者,您可以检查以下代码:
@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)
}
}
}
这部分将为整个应用程序创建一个“通用” View 模型。以这种方式,创建了
ViewModel
并分配了参数。之后,您需要在Singleton模块中实现factory模块,并将其包括在组件中。@Component(
modules = [... ViewModelModule::class]
)
interface AppCompoenent{}
现在有趣的部分:
@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 支持多重绑定(bind),因此您可以根据需要随意绑定(bind)
ViewModels
。ViewModelKey:
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER
)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
您基本上是将值放在哈希图中。这些值是您的
ViewModel
。打建立!完成后,您只需在片段中插入一个
ViewModelProvider.Facory
。比起您的ViewModel
,您可以:class MyViewModel @Inject constructor(
private val dependency: YourDependency
) : ViewModel() {}
明确您对评论的要求。首先,虽然我不建议学习这种方式,但我并没有特别的需要知道
DaggerViewModelFactory
内部发生了什么,因为我是“始终知道正在发生的事情”的坚定拥护者。仅供参考,DaggerViewModelFactory
只是一个接受Map
的类,每个类都将ViewModel
扩展为键,并将该类依赖项作为值。在使用Provider<T>
时,Dagger知道如何查找那些依赖项,但是直到您调用provider.get()
时,它们才带给您。可以将其视为懒惰的初始化。现在检查
modelClass.isAssignableFrom(it.key)
。它只是检查该类是否真的扩展了ViewModel
。至于第二个问题,了解第一部分很重要。由于
Dagger
支持多重绑定(bind),这意味着您可以使用Map<Key, Value>
提供依赖项。例如,Map<HomeViewModel, Provider<ViewModel>>
基本上会告诉dagger,这给了我HomeViewModel
的依赖项。 Dagger 会说:如何知道HomeViewModel
的依赖性?您会回答:我已经为此定义了一个键,它是HomeViewModel
类本身。因此,您只需创建一个注释,并将其与@Binds
和@IntoMap
结合使用,然后Dagger将在后台执行map.put(HomeViewModel::class, AndDependencies)
。