Как определяется момент уничтожения ViewModel
Что проверяют
Понимаете ли вы механизм, а не только фразу «ViewModel переживает поворот экрана». Интервьюер ждёт, что вы назовёте ViewModelStore, проверку isChangingConfigurations() и разницу между владельцами. Следом спрашивают, что будет со ViewModel при смерти процесса.
Как отвечать
ViewModel живёт не в Activity, а в ViewModelStore, которым владеет ViewModelStoreOwner. Когда владелец уходит окончательно, у хранилища вызывается clear(), и оно вызывает onCleared() у каждой своей ViewModel. От владельца и зависит момент уничтожения:
- Activity:
ComponentActivityподписана на свой жизненный цикл и наON_DESTROYпроверяетisChangingConfigurations(). При повороте или смене темы хранилище не чистится и передаётся новому экземпляру через non-configuration instance. Приfinish()хранилище очищается; - Fragment: хранилища фрагментов держит
FragmentManagerв своей служебной ViewModel. Очистка происходит, когда фрагмент удалён насовсем, например снят со стека, а не пересоздаётся из-за смены конфигурации; - Navigation: владелец это
NavBackStackEntry, ViewModel экрана очищается, когда запись снимают со стека; - Compose:
viewModel()берёт ближайшегоLocalViewModelStoreOwner, поэтому срок жизни задаёт Activity, фрагмент или запись навигации, а не composable-функция.
При очистке отменяется viewModelScope, так что его корутины завершатся сами. Прочие ресурсы освобождайте в onCleared() или регистрируйте через addCloseable().
Смерть процесса отдельный случай: система убивает процесс в фоне без вызова onCleared(), и содержимое ViewModel пропадает. Переживает только то, что сохранено через SavedStateHandle или в постоянном хранилище.
Где спотыкаются
Путают причину и следствие: говорят, что ViewModel уничтожается «при вызове onCleared()». Это колбэк, который вызывает хранилище в момент очистки.
Уверены, что ViewModel переживает всё. Смерть процесса она не переживает, а на слабых устройствах это частый сценарий.
Держат во ViewModel ссылку на Activity, View или Context экрана. После поворота это утечка старой Activity; если нужен контекст, берут AndroidViewModel с Application.