Что ViewModel может пережить
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что может пережить ViewModel
ViewModel — это компонент архитектуры Android, специально разработанный для хранения и управления UI-данными, связанными с жизненным циклом. Его ключевая особенность — умение «переживать» определенные конфигурационные изменения активности или фрагмента, что позволяет сохранить данные и избежать их потерь при таких событиях.
Конфигурационные изменения, которые ViewModel переживает
ViewModel сохраняется во время следующих изменений конфигурации устройства, когда система уничтожает и пересоздает Activity/Fragment:
- Изменение ориентации экрана (с портретной на ландшафтную и обратно).
- Изменение языка или региональных настроек системы.
- Изменение размера окна (например, при переходе в режим разделенного экрана или Picture-in-Picture).
- Подключение или отключение физической клавиатуры.
- Изменение темы или ночного режима (Dark/Light theme).
Как это работает технически
ViewModel не переживает эти события «сам по себе». Его жизненным циклом управляет ViewModelStore, принадлежащий ComponentActivity (или Fragment). При уничтожении Activity из-за конфигурационных изменений (isChangingConfigurations = true) ViewModelStore не очищается, а передается новому экземпляру Activity. Когда же Activity уничтожается окончательно (например, пользователь нажал «Назад» или вызван finish()), ViewModelStore очищается, и в методе ViewModel.onCleared() можно освободить ресурсы.
class MainViewModel : ViewModel() {
private val _userData = MutableLiveData<User>()
val userData: LiveData<User> = _userData
// Этот метод будет вызван, когда ViewModel окончательно уничтожится
override fun onCleared() {
super.onCleared()
// Освобождаем ресурсы, например, отменяем подписки
}
}
Чего ViewModel НЕ переживает (о чем важно помнить)
Несмотря на свою устойчивость, ViewModel — не вечный компонент. Он НЕ переживает следующие сценарии:
- Окончательное уничтожение Activity/Fragment. Когда пользователь выходит из приложения (нажимает кнопку «Назад») или явно вызывается
finish(), все связанные ViewModel'и очищаются. - Завершение процесса системы (Process death). Если системе критически не хватает памяти, она может полностью завершить процесс вашего приложения в фоне. ViewModel, хранящиеся в оперативной памяти, будут уничтожены. Для сохранения данных в таких сценариях используется комбинация ViewModel и
SavedStateHandleили постоянное хранение (Room, DataStore).
class MainViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// Сохраняем критически важные данные для восстановления после Process death
var uiState: String
get() = savedStateHandle["key"] ?: ""
set(value) = savedStateHandle.set("key", value)
}
Практические выводы и рекомендации
- Используйте ViewModel для: кэширования UI-данных, выполнения бизнес-логики, хранения LiveData/StateFlow, которые должны сохраняться при повороте экрана.
- Не используйте ViewModel для: хранения ссылок на View, Context или любые объекты, напрямую связанные с жизненным циклом UI. Это приведет к утечкам памяти.
- Сочетайте с другими компонентами:
* **SavedStateHandle** – для сохранения небольшого объема критических данных (ID, простые состояния), чтобы пережить `Process death`.
* **Repository + Room/DataStore** – для постоянного хранения данных, которые должны сохраняться между сессиями приложения.
Таким образом, ViewModel — это надежный контейнер данных для конфигурационных изменений, но не для всех случаев жизни приложения. Понимание границ его «выживаемости» — ключ к построению отзывчивых и стабильных Android-приложений, которые корректно управляют своими данными и ресурсами.