Как view взаимодействует с viewModel в MVVM и как реализуется обновление состояния
Что проверяют
Понимаете ли вы однонаправленный поток данных: View отправляет события, ViewModel отдаёт состояние, и никто не лезет в чужую зону. Следом обычно спрашивают, как собирать поток с учётом жизненного цикла и что делать с одноразовыми событиями вроде навигации или тоста.
Как отвечать
Схема современного Android-проекта выглядит так:
- состояние: ViewModel держит приватный
MutableStateFlow<UiState>и наружу отдаёт толькоStateFlow.UiStateэто неизменяемый data class с полями экрана: список, флаг загрузки, ошибка; - события: View не меняет данные, она вызывает методы ViewModel вроде
onRetryClick()илиonQueryChanged(text); - обновление: внутри ViewModel
_uiState.update { it.copy(isLoading = true) }. Функцияupdateатомарна, в отличие от чтения и записиvalueв два шага. Асинхронная работа идёт вviewModelScopeи отменяется сама, когда ViewModel уничтожается; - подписка в Compose:
val state by viewModel.uiState.collectAsStateWithLifecycle(), сбор останавливается, когда экран уходит в фон; - подписка во View-системе:
lifecycleScope.launchплюсrepeatOnLifecycle(Lifecycle.State.STARTED), во фрагменте черезviewLifecycleOwner.
ViewModel переживает поворот экрана, потому что хранится в ViewModelStore активити или фрагмента. Смерть процесса она не переживает: то, что должно восстановиться, кладут в SavedStateHandle. Если источник данных сам по себе Flow из репозитория, его удобно превращать в состояние через stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), initial).
LiveData по-прежнему работает, но в новых проектах её вытеснили StateFlow и корутины.
Где спотыкаются
Передают в ViewModel Context, Activity или ссылку на View. После поворота старая активити остаётся в памяти, это прямая утечка.
Собирают Flow через lifecycleScope.launch без repeatOnLifecycle. Подписка продолжает работать в фоне, а во фрагменте с this вместо viewLifecycleOwner ещё и множится при возврате по back stack.
Шлют навигацию через SharedFlow без буфера. Событие, отправленное во время поворота, теряется, поэтому Google советует моделировать такие вещи как часть состояния.