Как Android сохраняет состояние ViewModel
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Как Android сохраняет состояние ViewModel?
ViewModel — это компонент архитектуры Android Jetpack, предназначенный для управления данными, связанными с UI, и их сохранения во время конфигурационных изменений (например, поворот экрана). Важно понимать, что ViewModel не сохраняет свое состояние автоматически в смысле долговременного сохранения (например, в SharedPreferences или базу данных). Вместо этого она "переживает" временные изменения конфигурации, сохраняя свои данные в памяти.
Механизм сохранения во время конфигурационных изменений
Когда происходит изменение конфигурации (например, поворот экрана), Activity уничтожается и создается снова. Однако связанный с ней ViewModel остается в памяти. Это достигается благодаря тому, что ViewModel хранится в специальном объекте — ViewModelStore, который принадлежит ComponentActivity (или Fragment, если используется ViewModel в Fragment). ComponentActivity переопределяет метод onRetainNonConfigurationInstance() (или использует более современный механизм через ViewModelStoreOwner и SavedStateRegistry), чтобы сохранить этот ViewModelStore при изменении конфигурации и передать его новой инстанции Activity.
// Пример создания ViewModel, который будет сохранен при повороте экрана
class MyActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// viewModel останется тем же объектом после поворота
}
}
Сохранение состояния для восстановления после полного уничтожения процесса
Если система полностью уничтожает процесс приложения (например, из-за недостатка памяти), тогда все объекты в памяти, включая ViewModel, теряются. Для сохранения критических данных в таком сценарии используется SavedStateHandle.
SavedStateHandle — это компонент, который интегрируется с системой сохранения состояния Android. Он позволяет ViewModel сохранять и восстанавливать небольшое количество данных через механизм onSaveInstanceState() Activity/Fragment.
// Пример ViewModel с SavedStateHandle
class MyViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// Сохраняем состояние через SavedStateHandle
var userInput: String by savedStateHandle.getLiveData("user_input_key")
fun saveData(input: String) {
savedStateHandle.set("user_input_key", input)
}
// Восстановление данных при ресоздании процесса
fun getSavedData(): String? {
return savedStateHandle.get("user_input_key")
}
}
Ключевые моменты работы механизма
- ViewModelStore и ComponentActivity: ViewModel хранится в ViewModelStore, который ComponentActivity сохраняет при изменении конфигурации и передает новой инстанции.
- SavedStateHandle для полного уничтожения процесса: Если процесс убивается системой, данные можно восстановить через SavedStateHandle, который работает совместно с системными методами
onSaveInstanceState()иonRestoreInstanceState(). - ViewModel не сохраняет состояние автоматически в долговременное хранилище: Для сохранения данных между полными запусками приложения (например, после закрытия) необходимо использовать другие механизмы: SharedPreferences, Room Database, DataStore.
- Жизненный цикл: ViewModel очищается (и вызывается метод
onCleared()), когда ее владелец (Activity/Fragment) окончательно уничтожается (не из-за конфигурационного изменения).
// Пример очистки ресурсов в ViewModel при окончательном уничтожении
class MyViewModel : ViewModel() {
private val someResource = SomeHeavyResource()
override fun onCleared() {
super.onCleared()
someResource.release() // Освобождаем ресурсы
}
}
Практическое применение и рекомендации
- Используйте обычный ViewModel для сохранения данных во время поворота экрана или других временных изменений конфигурации.
- Для сохранения критического состояния UI (например, текст в поле ввода), которое должно быть восстановлено после убийства процесса, используйте SavedStateHandle.
- Для настоящего долговременного сохранения данных (настройки пользователя, список задач) комбинируйте ViewModel с репозиторием, который работает с Room или DataStore.
Таким образом, сохранение состояния ViewModel в Android — это двухуровневый механизм: в памяти для конфигурационных изменений и через SavedStateHandle для восстановления после уничтожения процесса. Это позволяет эффективно отделять временные UI-данные от долговременных бизнес-данных.