Сравнение ViewModel и сохраненного состояния экземпляра
В сохраненном состоянии экземпляра запись activity хранится
после уничтожения или изменения конфигурации. При первом
запуске activity сохраненное состояние экземпляра нулевое.
При повороте устройства операционная система вызывает
функцию
onSaveInstanceState(Bundle)
от вашей activity.
Затем ОС передает данные, которые были сохранены в наборе,
функции
OnCreate(Bundle?)
.
Если сохраненное состояние экземпляра защищает и от
изменений конфигурации и от уничтожения процесса, зачем
вообще нужен
ViewModel
? Приложение GeoQuiz настолько
простое, что можно было бы обойтись одним сохраненным
состоянием экземпляра.
Однако в большинстве приложений нельзя ограничиться
небольшим, жестко заданным набором данных, как в GeoQuiz.
Большинство приложений динамически используют данные из
базы данных, из интернета или из двух мест одновременно.
Эти операции являются асинхронными, часто бывают
медленными и тратят заряд аккумулятора и трафик. Связывать
эти операции с жизненным циклом activity сложно и чревато
ошибками.
ViewModel
проявляет себя во всей красе, когда вы
используете его, чтобы организовать динамическую работу с
данными в главах 11 и 24. Например,
ViewModel
позволяет
возобновить
операцию
загрузки
после
изменения
конфигурации. В нем также есть простой способ сохранить
данные, которые не получалось сохранить в памяти после
изменения конфигурации. И, как вы уже видели,
ViewModel
автоматически очищается, когда пользователь завершает
activity.
ViewModel
не так хорошо работает при уничтожении
процесса, так как он удаляется из памяти вместе с процессом.
Здесь уже на сцену выходит сохраненное состояние экземпляра.
Но и у него есть свои ограничения. Поскольку сохраненное
состояние экземпляра сериализуется на диск, не стоит
сохранять крупные или сложные объекты.
На момент написания этой главы команда Android активно
работала над улучшением опыта разработчиков при работе с
ViewModel
. Появилась новая библиотека
lifecycle-
viewmodel-savedstate
, выпущенная с целью позволить
ViewModel
сохранять свое состояние после завершения
процесса. Это должно облегчить некоторые из трудностей
использования
ViewModel
.
Вопрос, что лучше,
ViewModel
или сохраненное состояние
экземпляра, вообще не стоит. Грамотные разработчики
используют оба эти инструмента, в зависимости от ситуации.
Используйте сохраненное состояние экземпляра, чтобы
сохранить
минимальное
количество
информации,
необходимой для воссоздания состояния пользовательского
интерфейса (например, номер текущего вопроса). Используйте
ViewModel
,
чтобы
кэшировать
множество
данных,
необходимых для восстановления интерфейса после изменения
конфигурации. Когда activity воссоздается после смерти
процесса, используйте информацию о сохраненном состоянии
экземпляра, чтобы настроить
ViewModel
, как будто
ViewModel
и activity не были уничтожены.
На момент написания книги не существует простого способа
определить, была ли activity воссоздана после уничтожения
процесса или изменения конфигурации. Почему это важно?
ViewModel
остается в памяти во время изменения
конфигурации. Поэтому если вы используете сохраненное
состояние экземпляра данных для обновления
ViewModel
после изменения конфигурации, приложение делает лишнюю
работу, которая заставляет пользователя ждать или тратить
лишние ресурсы.
Один из способов решить эту проблему — сделать ваш
ViewModel
немного умнее. Если установка значения
ViewModel
может привести к лишней работе, сначала
проверьте, достаточно ли актуальны данные, прежде чем
выполнять работу по их извлечению:
class SomeFancyViewModel : ViewModel() {
...
fun setCurrentIndex(index: Int) {
if (index != currentIndex) {
currentIndex = index
// Загрузка текущего вопроса из БД
}
}
}
Ни
ViewModel
, ни сохраненное состояние экземпляра не
подходят для длительного хранения. Если вам нужно хранить
данные в течение длительного срока, пока приложение
установлено на устройстве, независимо от состояния вашей
activity, нужно более постоянное решение. Вы узнаете о двух
локальных вариантах постоянного хранения данных: базы
данных из главы 11 и общие настройки из главы 26. Общие
настройки отлично подходят для необъемных и простых
данных. Локальная база данных — лучший вариант для более
крупных и сложных данных. Помимо локальной памяти, можно
хранить данные на удаленном сервере. Вы узнаете, как
получить доступ к данным веб-сервера, из главы 24.
Если в GeoQuiz много вопросов, возможно, имеет смысл
хранить их в базе данных или на веб-сервере, а не жестко
прописывать в
ViewModel
. Поскольку вопросы являются
константами, имеет смысл хранить их независимо от состояния
жизненного цикла activity. Однако доступ к базам данных — это
относительно медленная операция по сравнению с доступом к
значениям в памяти. Так что имеет смысл загрузить то, что вам
нужно для отображения пользовательского интерфейса, и
сохранить это в памяти, а интерфейс выводить через
ViewModel
.
В этой главе мы исправили ошибки потери состояния у
приложения GeoQuiz путем правильного учета изменений
конфигурации и уничтожения процесса. В следующей главе вы
узнаете, как использовать инструменты отладки Android Studio,
чтобы устранить другие ошибки, которые также имеют место
быть.
Do'stlaringiz bilan baham: |