questionTextView.setText(questionTextRe
sId)
}
private fun checkAnswer(userAnswer:
Boolean) {
val correctAnswer =
questionBank[currentIndex].answer
val
correctAnswer
=
quizViewModel.currentQuestionAnswer
...
}
Запустите GeoQuiz,
нажмите
NEXT
, а затем поверните
устройство или эмулятор. Независимо от того, сколько раз вы
выполните поворот, новый экземпляр
MainActivity
будет
«помнить», на каком вопросе вы остановились. Можете
порадоваться, ведь вы решили проблему потери прогресса при
повороте.
Но не слишком сильно радуйтесь. В
программе есть еще
одна незаметная ошибка.
Сохранение данных после завершения процесса
Конфигурация
изменяется
не
только
тогда,
когда
операционная система может уничтожить activity, даже если
пользователь не собирался этого делать. Каждое приложение
получает свой собственный процесс (а именно процесс Linux),
содержащий один поток для работы с интерфейсом и память
для хранения объектов.
Процесс приложения может быть завершен ОС, если
пользователь долго не
пользуется приложением, и Android
нужно освободить оперативную память. Когда процесс
приложения уничтожается, все объекты, хранящиеся в памяти
этого
процесса, тоже уничтожаются. (Подробнее о процессах
приложений вы узнаете из главы 23.)
Процессы,
содержащие
выполняющиеся
или
приостановленные activity, имеют более высокий приоритет по
сравнению с другими процессами. Когда ОС нужно
высвободить ресурсы, она сначала будет завершать процессы с
низким приоритетом. На практике это означает, что процесс,
содержащий видимую activity, уничтожаться не будет. Если это
произошло — значит, с устройством что-то не так (и
завершение приложения в этом случае — меньшая из проблем).
Но вот остановленные activity вполне можно уничтожить.
Так, например, если пользователь нажимает кнопку «Главный
экран», после чего смотрит
видео или играет в игру, процесс
вашего приложения может быть уничтожен.
(На момент написания отдельно взятая activity не
уничтожается при недостатке памяти, даже если в
документации говорится, что это так.
Вместо этого Android
удаляет из памяти весь процесс приложения, а заодно и все
activity.)
Когда операционная система уничтожает процесс в
приложении, все activity приложения и
ViewModel
-и будут
удалены. И ОС насчет аккуратного завершения церемониться
не будет и вызывать
никакие activity и функции обратного
вызова жизненного цикла
ViewModel
тоже не станет.
Итак,
как
можно
сохранить
состояние
данных
пользовательского интерфейса и использовать их для
восстановления activity, чтобы пользователь вообще не
замечал, что activity была уничтожена? Один из способов
сделать это — хранить данные в виде
сохраненного состояния
экземпляра. Сохраненное состояние экземпляра — это данные,
которые ОС временно сохраняет за пределами activity. Вы
можете добавить значения в сохраненное состояние
экземпляра
путем
переопределения
Activity.onSaveInstanceState(Bundle)
.
ОС вызывает
Activity.onSaveInstanceState(Bundle)
всякий раз, когда незавершенная activity переходит в
остановленное состояние (например, когда пользователь
нажимает кнопку «Главный экран», а затем запускает другое
приложение). Это
время очень важно, потому что
остановленные activity отмечаются как
killable. Если процесс
приложения будет завершен из-за низкого приоритета, вы
можете
быть
уверены,
что
функция
Activity.onSaveInstanceState(Bundle)
уже
была
вызвана.
Реализация
по
умолчанию
функции
onSaveInstanceState(Bundle)
сохраняет все представления
и состояние activity в объекте
Bundle
. Это
такая структура,
которая отображает строковые ключи к значениям
определенных типов.
Вы уже видели объект
Bundle
ранее. Он передается в
функцию
OnCreate(Bundle?)
:
override
fun
onCreate(savedInstanceState:
Bundle?) {
super.onCreate(savedInstanceState)
...
}
При переопределении функции
onCreate(Bundle?)
вы
вызываете функцию
OnCreate(Bundle?)
на суперклассе своей
activity и передаете набор, который только что получили. В
реализации суперкласса сохраненное состояние представлений
извлекается и используется для повторного создания иерархии
видов activity.
Do'stlaringiz bilan baham: