← Назад к вопросам

Что происходит с ViewModel при пересоздании View

1.0 Junior🔥 241 комментариев
#Android компоненты#UI и вёрстка

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Поведение ViewModel при пересоздании View

ViewModel — ключевой компонент архитектурного компонента Android (Jetpack), разработанный специально для разделения бизнес-логики и данных от жизненного цикла UI-компонентов (Activity/Fragment). Его главная задача — сохранять данные при изменениях конфигурации, которые приводят к пересозданию View (Activity или Fragment).

Механизм сохранения ViewModel

Когда Activity или Fragment пересоздается (например, при повороте устройства, изменении языка, переходе в режим многоконного окна), происходит следующее:

  1. Активность уничтожается и создается снова. Все привязанные к ней View также уничтожаются.
  2. ViewModel, связанный с этой Activity/Fragment, НЕ уничтожается. Он остается в памяти.
  3. Новая 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 напрямую, чтобы избежать утечек памяти.

Пример жизненного цикла

Рассмотрим сценарий поворота устройства:

  1. Activity A создана, получает ViewModel VM.
  2. VM инициализируется, загружает данные из сети в LiveData.
  3. Пользователь поворачивает устройство → Activity A уничтожается (onDestroy()), но VM остается.
  4. Система создает Activity B (новый экземпляр после поворота).
  5. Activity B в onCreate() запрашивает ViewModel через viewModels() делегат.
  6. ViewModelProvider возвращает существующий экземпляр VM из хранилища.
  7. 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.

Что происходит с ViewModel при пересоздании View | PrepBro