Создание ViewModel с зависимостями . Часть Android Jetpack .
Следуя лучшим практикам внедрения зависимостей , ViewModels могут принимать зависимости в качестве параметров в своем конструкторе. В основном это типы из предметной области или уровня данных . Поскольку фреймворк предоставляет ViewModels, для создания их экземпляров требуется специальный механизм. Этот механизм — интерфейс ViewModelProvider.Factory . Только реализации этого интерфейса могут создавать экземпляры ViewModels в нужной области видимости .
ViewModels with CreationExtras
Если класс ViewModel получает зависимости в своем конструкторе, предоставьте фабрику, реализующую интерфейс ViewModelProvider.Factory . Переопределите функцию create(Class<T>, CreationExtras) , чтобы предоставить новый экземпляр ViewModel.
CreationExtras позволяет получить доступ к необходимой информации, которая помогает создать экземпляр ViewModel. Вот список ключей, к которым можно получить доступ из extras:
| Ключ | Функциональность |
|---|---|
ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY | Предоставляет доступ к пользовательскому ключу, переданному в метод ViewModelProvider.get() . |
ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY | Предоставляет доступ к экземпляру класса Application . |
SavedStateHandleSupport.DEFAULT_ARGS_KEY | Предоставляет доступ к набору аргументов, которые следует использовать для создания SavedStateHandle . |
SavedStateHandleSupport.SAVED_STATE_REGISTRY_OWNER_KEY | Предоставляет доступ к объекту SavedStateRegistryOwner , используемому для построения ViewModel . |
SavedStateHandleSupport.VIEW_MODEL_STORE_OWNER_KEY | Предоставляет доступ к объекту ViewModelStoreOwner , используемому для построения ViewModel . |
Для создания нового экземпляра SavedStateHandle используйте функцию CreationExtras.createSavedStateHandle() и передайте её в ViewModel.
CreationExtras с APPLICATION_KEY
Ниже приведён пример того, как предоставить экземпляр 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.
Вы можете передавать зависимости в вашу ViewModel через CreationExtras , создав пользовательский ключ. Это может быть полезно, если ваша ViewModel зависит от объектов, недоступных через класс Application и APPLICATION_KEY . Например, когда ваша ViewModel создается внутри модуля Kotlin Multiplatform и, следовательно, не имеет доступа к зависимостям 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,
)
}
}
}
}
Вы можете создать экземпляр ViewModel с помощью CreationExtras.Key непосредственно в ваших компонуемых объектах.
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 и зависимостях см. следующие дополнительные ресурсы:
Документация
Просмотры контента
{% verbatim %}Рекомендуем вам
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- Модуль сохранения состояния для ViewModel
- Сохранение состояний пользовательского интерфейса