Что происходит с ViewModel при пересоздании View
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Поведение ViewModel при пересоздании View
ViewModel — ключевой компонент архитектурного компонента Android (Jetpack), разработанный специально для разделения бизнес-логики и данных от жизненного цикла UI-компонентов (Activity/Fragment). Его главная задача — сохранять данные при изменениях конфигурации, которые приводят к пересозданию View (Activity или Fragment).
Механизм сохранения ViewModel
Когда Activity или Fragment пересоздается (например, при повороте устройства, изменении языка, переходе в режим многоконного окна), происходит следующее:
- Активность уничтожается и создается снова. Все привязанные к ней View также уничтожаются.
- ViewModel, связанный с этой Activity/Fragment, НЕ уничтожается. Он остается в памяти.
- Новая Activity/Fragment автоматически получает тот же экземпляр ViewModel через механизм ViewModelProvider.
Это достигается благодаря тому, что ViewModel хранится в специальном хранилище — ViewModelStore, которое принадлежит не самой Activity, а более долгоживущему компоненту.
Пример получения ViewModel в Activity
class MyActivity : AppCompatActivity() {
// ViewModel будет сохраняться при пересоздании Activity
private val myViewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// myViewModel содержит данные, которые были в нем до пересоздания Activity
val data = myViewModel.liveData.value
// Обновляем UI с сохраненными данными
}
}
Как именно работает сохранение
- Для Activity:
ViewModelStoreассоциируется с объектом ViewModelStoreOwner. Для Activity это —ComponentActivity(базовый класс дляAppCompatActivity). ЕгоViewModelStoreсохраняется между изменениями конфигурации. - Для Fragment:
ViewModelStoreпринадлежит Fragment, но если Fragment находится внутри Activity, его жизнь также может зависеть от жизненного цикла родителя.
Ключевая деталь: ViewModel сохраняется, пока его ViewModelStoreOwner (Activity/Fragment) не будет окончательно уничтожен (не из-за изменения конфигурации, а из-за завершения работы приложения или явного закрытия Activity).
Что сохраняется и что не сохраняется
- Сохраняется: Все данные, хранящиеся в полях ViewModel (например, LiveData, StateFlow, обычные переменные).
- Не сохраняется и требует отдельной обработки:
* Состояние UI-элементов (скролл позиция, текст в EditText). Для этого используется механизм **сохранения состояния View** (`onSaveInstanceState()`).
* Ссылки на контекст Activity или View. Их нельзя хранить в ViewModel напрямую, чтобы избежать утечек памяти.
Пример жизненного цикла
Рассмотрим сценарий поворота устройства:
- Activity A создана, получает
ViewModel VM. - VM инициализируется, загружает данные из сети в
LiveData. - Пользователь поворачивает устройство → Activity A уничтожается (
onDestroy()), но VM остается. - Система создает Activity B (новый экземпляр после поворота).
- Activity B в
onCreate()запрашивает ViewModel черезviewModels()делегат. - ViewModelProvider возвращает существующий экземпляр VM из хранилища.
- Activity B сразу получает доступ к уже загруженным данным в
LiveDataи может отобразить их без повторной загрузки.
Особенности и ограничения
- ViewModel не переживает окончательное уничтожение Activity. Если пользователь закрывает Activity (нажав BACK), или система убивает процесс приложения, ViewModel также уничтожается.
- Если ViewModel требуется сохранить данные для последующего восстановления даже после окончательного уничтожения, необходимо использовать персистентное хранилище (база данных, SharedPreferences) или механизм
SavedStateHandle.
Использование SavedStateHandle для сохранения критичных данных
class MyViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
// SavedStateHandle позволяет сохранять небольшие данные
// даже после полного уничтожения Activity
private val userId: MutableLiveData<String> = savedStateHandle.getLiveData("userId")
fun setUserId(id: String) {
userId.value = id
// Данные будут доступны при повторном создании Activity из сохраненного состояния
}
}
Вывод
ViewModel специально разработан для устойчивости к пересозданию View, что делает его идеальным хранилищем для управляющих данных приложения (состояние UI, результаты сетевых запросов, список элементов). Это устраняет необходимость ручного сохранения и восстановления данных при изменении конфигурации, упрощает код и предотвращает утечки данных. Однако для сохранения моментального состояния UI-компонентов необходимо комбинировать его с механизмом onSaveInstanceState или SavedStateHandle.