Шаг 257.
Основы Kotlin.
Первое Android-приложение на Kotlin. Преобразование в расширение

    На этом шаге мы рассмотрим порядок выполнения такого преобразования.

    Сериализация и десериализация сохраненного состояния работают исправно, но этот код можно улучшить. Обратите внимание, что сейчас надо вручную указывать ключ и тип данных (выполнять приведение к типу CharacterData), когда вы возвращаете и передаете CharacterData в savedInstanceState:

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)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // setContentView(R.layout.activity_main)

        val binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        characterData = savedInstanceState?.let {
            it.getSerializable(CHARACTER_DATA_KEY)
                    as CharacterGenerator.CharacterData
        } ?: CharacterGenerator.generate()

        .   .   .   .
    }
    .   .   .   .
}

    Можно улучшить код, добавив объявление свойства-расширения в MainActivity.kt.

private const val CHARACTER_DATA_KEY = "CHARACTER_DATA_KEY"

private var Bundle.characterData
    get() = getSerializable(CHARACTER_DATA_KEY) as CharacterGenerator.CharacterData
    set(value) = putSerializable(CHARACTER_DATA_KEY, value)

class MainActivity : AppCompatActivity() {
    .   .   .   .
}


Рис.1. Объявление свойства-расширения в characterData (MainActivity.kt)

    Теперь можно обращаться к characterData в сохраненном состоянии экземпляра как к свойству. Вам больше не нужен ключ для извлечения данных, а также не надо приводить тип Serializable к CharacterType после извлечения.

    Свойство-расширение обеспечивает явную абстракцию над API Bundle, избавляя вас от необходимости помнить, как хранятся характеристики персонажа и каким ключом надо пользоваться, когда потребуется прочесть или записать characterData.

    Теперь используем свойство-расширение в функциях onSaveInstanceState() и onCreate().

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.characterData = characterData
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // setContentView(R.layout.activity_main)

        val binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        characterData = savedInstanceState?.characterData ?:
                CharacterGenerator.generate()

        binding.generateButton.setOnClickListener {
            characterData = CharacterGenerator.generate()
            displayCharacterData(binding)
        }

        displayCharacterData(binding)

    }

    .   .   .   .
}
Файл с проектом можно взять здесь.


Рис.2. Использование нового свойства-расширения (MainActivity.kt)

    Снова запустите Samodelkin, пройдя по всем возможностям приложения, поворачивая экран в эмуляторе и нажимая кнопку GENERATE. Вы увидите, что данные персонажа отображаются корректно.

    Поздравляем! Вы создали свое первое приложение для Android на Kotlin. Вы узнали о некоторых возможностях, поддерживаемых Kotlin при работе с кодом Java, на котором написан фреймворк Android. И наконец, вы узнали, как возможности Kotlin, такие как расширения и стандартные функции, могут сделать код Android-приложения чище.

    В дальнейшем вы познакомитесь с сопрограммами Kotlin - экспериментальной, легковесной и элегантной альтернативой другим моделям выполнения работы в фоновом режиме.

    На следующем шаге мы рассмотрим возможности некоторых библиотек.




Предыдущий шаг Содержание Следующий шаг