创建具有依赖项的 ViewModel Android Jetpack 的一部分。
按照依赖项注入的最佳实践,ViewModel 可以在其构造函数中将依赖项作为参数。这大多是网域层或数据层中的类型。由于框架提供 ViewModel,因此需要一种特殊机制来创建 ViewModel 的实例。该机制是 ViewModelProvider.Factory 接口。只有此接口的实现才能在适当的作用域内实例化 ViewModel。
包含 CreationExtras 的 ViewModel
如果 ViewModel 类在其构造函数中接收依赖项,请提供用于实现 ViewModelProvider.Factory 接口的工厂。替换 create(Class<T>, CreationExtras) 函数以提供 ViewModel 的新实例。
借助 CreationExtras,您可以访问有助于实例化 ViewModel 的相关信息。下面列出了可以通过 extra 访问的键:
| 键 | 功能 |
|---|---|
ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY |
提供对您传递给 ViewModelProvider.get() 的自定义键的访问权限。 |
ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY |
提供对 Application 类实例的访问权限。 |
SavedStateHandleSupport.DEFAULT_ARGS_KEY |
提供对您在构造 SavedStateHandle 时应使用的参数 bundle 的访问权限。 |
SavedStateHandleSupport.SAVED_STATE_REGISTRY_OWNER_KEY |
提供对用于构造 ViewModel 的 SavedStateRegistryOwner 的访问权限。 |
SavedStateHandleSupport.VIEW_MODEL_STORE_OWNER_KEY |
提供对用于构造 ViewModel 的 ViewModelStoreOwner 的访问权限。 |
如需创建 SavedStateHandle 的新实例,请使用 CreationExtras.createSavedStateHandle() 函数并将其传递给 ViewModel。
包含 APPLICATION_KEY 的 CreationExtras
以下示例说明了如何提供 ViewModel 的实例,该实例会将作用域限定为 Application 类的存储库和 SavedStateHandle 作为依赖项:
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.createSavedStateHandle
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
class MyViewModel(
private val myRepository: MyRepository,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// ViewModel logic
// ...
// Define ViewModel factory in a companion object
companion object {
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
val savedStateHandle = createSavedStateHandle()
val myRepository = (this[APPLICATION_KEY] as MyApplication).myRepository
MyViewModel(
myRepository = myRepository,
savedStateHandle = savedStateHandle
)
}
}
}
}
然后,您可以在检索 ViewModel 的实例时使用此工厂:
import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun MyScreen(
modifier: Modifier = Modifier,
viewModel: MyViewModel = viewModel(factory = MyViewModel.Factory)
) {
// ...
}
将自定义参数作为 CreationExtras 传递
您可以通过创建自定义键,通过 CreationExtras 将依赖项传递给 ViewModel。
如果您的 ViewModel 依赖于无法通过 Application 类和 APPLICATION_KEY 访问的对象,这会非常有用。例如,当您的 ViewModel 在 Kotlin 多平台模块内创建时,它无法访问 Android 依赖项。
在此示例中,ViewModel 定义了一个自定义键,并在 ViewModelProvider.Factory 中使用了该键。
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
class MyViewModel(
private val myRepository: MyRepository,
) : ViewModel() {
// ViewModel logic
// Define ViewModel factory in a companion object
companion object {
// Define a custom key using the factory function
val MY_REPOSITORY_KEY = CreationExtras.Key<MyRepository>()
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
// Get the dependency in your factory
val myRepository = this[MY_REPOSITORY_KEY] as MyRepository
MyViewModel(
myRepository = myRepository,
)
}
}
}
}
您可以在可组合函数中直接使用 CreationExtras.Key 实例化 ViewModel。
import androidx.lifecycle.viewmodel.MutableCreationExtras
import androidx.lifecycle.viewmodel.compose.viewModel
// ...
@Composable
fun MyApp(myRepository: MyRepository) {
val extras = MutableCreationExtras().apply {
set(MyViewModel.MY_REPOSITORY_KEY, myRepository)
}
val viewModel: MyViewModel = viewModel(
factory = MyViewModel.Factory,
extras = extras,
)
}
其他资源
如需详细了解 ViewModel 和依赖项,请参阅下面列出的其他资源:
文档
查看内容
为您推荐
- 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
- ViewModel 的已保存状态模块
- 保存界面状态