ViewModel
ViewModel
Хранит состояние бизнес-логики экрана. Предоставляет состояние UI и инкапсулирует соответствующую бизнес-логику. Основное преимущество заключается в том что он кэширует состояние и сохраняет его при изменениях конфигурации. Это означает что вашему UI не нужно повторно получать данные при переходе между экранами или после изменений конфигурации, например при повороте экрана.
• при переходе на следующий экран ViewModel
должна жить.
• при переходе на предыдущий экран ViewModel
должна умереть.
AndroidViewModel
ViewModel
с контекстом приложения. Подклассы должны иметь конструктор, который принимает Application
в качестве единственного параметра.
Assisted
@HiltViewModel(assistedFactory = MyViewModel.Factory::class)
class MyViewModel @AssistedInject constructor(
@Assisted val userId: Int,
savedStateHandle: SavedStateHandle
): ViewModel() {
@AssistedFactory
interface Factory {
fun create(userId: Int): MyViewModel
}
}
@Composable
fun MyScreen(
userId: Int,
viewModel: MyViewModel = hiltViewModel(
creationCallback = { factory: MyViewModel.Factory -> factory.create(userId) }
)
) {}
ViewModelStore
Класс который хранит экземпляры ViewModel. Внутри лежит mutableMapOf<String, ViewModel>
где ключ - идентификатор модели. Каждая Activity, Fragment, View или Composable имеют собственный ViewModelStore который живет в течение lifecycle элемента. Класс ViewModelStore в andoridx-репозитории.
ViewModelStoreOwner
Интерфейс который обеспечивает доступ к ViewModelStore
.
ViewModelProvider
Класс отвечает за создание и получение ViewModel
. Есть методы get
и create
.
ViewModelProvider.Factory
Интерфейс который даёт нам метод для создания ViewModel
. По умолчанию используется DefaultViewModelProviderFactory
если мы не сделаем собственную реализацию. Кастомные Factory позволяют создавать ViewModel с параметрами конструктора что дает дополнительную гибкость.
Lifecycle
Когда мы запрашиваем ViewModel
- ViewModelProvider
проверяет существует ли такая модель. Если найдена - возвращается экземпляр. Если не найдена - ViewModelProvider.Factory
используется для создания новой ViewModel
и она потом сохраняется в ViewModelStore
. Созданная ViewModel
жива пока жив экран. Когда экран уничтожается - ViewModelStore
очищается и все хранящиеся в нем ViewModel
удаляются. Для каждой ViewModel
вызывается onCleared
.
Как сохраняется ViewModel?
ViewModel
не уничтожается при смене конфигурации. Объекты ViewModel
сохраняются в специальном хранилище - ViewModelStore
. Вновь созданный экран может получить доступ к существующему экземпляру ViewModel
.
SavedStateHandle
Key-value мапа. Передается в конструктор вьюмодели. Позволяет записывать и извлекать объекты из сохраненного состояния.
@HiltViewModel
class MyViewModel @Inject constructor(
savedStateHandle: SavedStateHandle
): ViewModel() {
private val id: Int? = savedStateHandle.get<Int>("id")
private val idStateFlow: StateFlow<Int> = savedStateHandle.getStateFlow("id", 0)
init {
savedStateHandle["id"] = 1
savedStateHandle.remove<Int>("id")
}
}
ViewModel. Вопросы на собесе
- Что такое ViewModel и какова его роль в архитектуре Android?
- Как ViewModel взаимодействует с жизненным циклом Activity или Fragment?
- Что такое SavedStateHandle и как его использовать в ViewModel?
- Как разделять ViewModel между несколькими Fragment в одной Activity?
- Как ViewModel переживает пересоздание Activity?
ViewModel
сохраняется вViewModelStore
, и новаяActivity
получает доступ к той жеViewModel
, избегая ее пересоздания.