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

Что ViewModel может пережить

2.0 Middle🔥 171 комментариев
#Android компоненты#Жизненный цикл и навигация

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

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

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

Что может пережить 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 — не вечный компонент. Он НЕ переживает следующие сценарии:

  1. Окончательное уничтожение Activity/Fragment. Когда пользователь выходит из приложения (нажимает кнопку «Назад») или явно вызывается finish(), все связанные ViewModel'и очищаются.
  2. Завершение процесса системы (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-приложений, которые корректно управляют своими данными и ресурсами.

Что ViewModel может пережить | PrepBro