На этом шаге мы рассмотрим реализацию указанного действия.
Ваше приложение создания персонажа понемногу улучшается. Теперь вы можете нажать кнопку GENERATE и создать персонажа с характеристиками, которые вас устроят. Но есть одна проблема. Чтобы увидеть ее, запустите эмулятор, а затем сымитируйте поворот экрана телефона, щелкнув на значке поворота в окне инструментов эмулятора (рисунок 1).
Рис.1. Имитируем поворот экрана
UI отобразит характеристики персонажа, отличные от полученных ранее, или вообще аварийно прекратит работу.
Изменение данных в UI обусловлено особенностями работы жизненного цикла активности Android. Когда устройство поворачивается (в Android это называется изменением конфигурации устройства), Android уничтожает и снова создает активность с пользовательским интерфейсом, повторно вызывая функцию onCreate() нового экземпляра класса MainActivity.
Один из способов исправить это недоразумение - перенести характеристики персонажа в следующий экземпляр активности, запомнив их в сохраненном состоянии экземпляра активности. В сохраненном состоянии экземпляра можно хранить данные, которые вы бы хотели использовать снова после повторного создания активности снова при изменении конфигурации объекта.
Сначала добавьте в класс MainActivity вызов операции сериализации характеристик персонажа.
private const val CHARACTER_DATA_KEY = "CHARACTER_DATA_KEY" class MainActivity : AppCompatActivity() { private var characterData = CharacterGenerator.generate() override fun onSaveInstanceState(savedInstanceState: Bundle) { super.onSaveInstanceState(savedInstanceState) savedInstanceState.putSerializable(CHARACTER_DATA_KEY, characterData) } . . . . }
Рис.2. Сериализация characterData (MainActivity.kt)
Сериализация - это процесс, с помощью которого сохраняются объекты. В ходе сериализации объект преобразуется в базовые типы, такие как String или Int. Только сериализованные объекты могут храниться в Bundle.
IntelliJ сообщите об ошибке в chacterData, так как вы пытаетесь передать несериализуемый объект в функцию putSerializable(). Чтобы исправить ошибку, надо добавить интерфейс Serializable в класс CharacterData - он станет сериализуемым.
. . . . object CharacterGenerator { data class CharacterData(val name: String, val race: String, val dex: String, val wis: String, val str: String) : Serializable . . . . }
Рис.3. Добавление поддержки сериализации в класс CharacterData (CharacterGenerator.kt)
Функция onSaveInstanceState() вызывается один раз до того, как активность будет уничтожена. Она позволяет сохранить состояние активности в аргументе savedInstanceState типа Bundle.
Вы добавили объект characterData в сохраненное состояние экземпляра, используя метод putSerializable(), который принимает ключ и экземпляр сериализуемого класса. Ключ - это константа, которая будет использована позже для извлечения сериализованного значения - экземпляра класса CharacterData, который вы расширили реализацией интерфейса Serializable.
На следующем шаге мы рассмотрим чтение сохраненного состояния экземпляра.