Android jetpack что это
Что нового в Jetpack
Jun 25, 2020 · 8 min read
Android Jetpack — это набор библиотек, направленных на то, чтобы помочь вам легко писать высококачественные приложения, поддерживая более старые версии Android. Спустя два года после запуска Jetpack мы наблюдаем огромное внедрение приложений от крупных команд разработчиков и тех, кто только начал работать. И это только начало: сегодня мы запускаем новые библиотеки, а также основные обновления существующих, над которыми мы работали в течение последнего года. Здесь можно найти расширенный видео-обзор последних обновлений в Jetpack.
Новое в Альфе
Рекомендуемая библиотека Hilt от Jetpack для инъекции зависимостей
Hilt — это новая библиотека Android, которая упрощает внедрение зависимостей (DI) в приложении. Hilt позволяет сосредоточиться только на важных частях определения и инъекции связок, не беспокоясь об управлении всеми настройками DI и настройкой связей (wiring).
Узнайте больше о Hilt и откройте для себя больше ссылок на связанные ресурсы в нашем блоге запуска.
Paging 3 — постепенная загрузка и отображение данных
Paging — это библиотека, которая помогает загружать и отображать небольшие фрагменты данных постепенно. Сегодня мы выпускаем Paging 3 — полностью переписанную библиотеку с использованием корутин Kotlin. Этот новый релиз добавляет очень востребованные функции, такие как разделители, верхние и нижние колонтитулы и преобразования списков, а также API для наблюдения за состоянием загрузки списка и методами повторной попытки и обновления.
Для получения дополнительной информации о Paging 3 ознакомьтесь с документацией и нашим codelab.
App Startup — инициализация компонентов при запуске приложения
Библиотека App Startup предоставляет простой и эффективный способ инициализации компонентов при запуске приложения. Вместо определения отдельных поставщиков контента для каждого компонента, который необходимо инициализировать, App Startup позволяет определить инициализаторов компонентов, совместно использующих одного поставщика контента. Это может значительно улучшить время запуска приложения.
Пример использования App Startup для улучшения времени инициализации WorkManager (библиотека, которая использует ContentProvider под капотом) после отключения ContentProvider в WorkManager:
Для получения дополнительной информации о App Startup ознакомьтесь с официальной документацией.
Интеграция IME с автоматическим заполнением
Упрощенная анимация с помощью core-animation и SeekableAnimatedVectorDrawable
core-animation адаптирует все функции, добавленные в API Animator со времен Ice Cream Sandwich, такие как пауза/продолжить и поиск.
Отладка базы данных с помощью Database Inspector в Android Studio
Отладка проблем с базой данных стала проще в бета-версии Android Studio 4.1 с новым Database Inspector. Этот инструмент позволяет проверять, запрашивать и изменять базы данных SQLite в запущенном приложении. Независимо от того, используете ли вы непосредственно Room или SQLite, вы можете начать отладку БД, выбрав в строке меню View > Tool Windows > Database Inspector. Узнайте больше об этом инструменте и о том, как его использовать, в этом блоге.
WindowManager — улучшенная поддержка форм-факторов устройств
Библиотека WindowManager — это новое дополнение к Android Jetpack, которое используется для поддержки новых форм-факторов, таких как складные смартфоны, экраны с “челкой” и другие. Она предоставляет общий API для различных функций WindowManager как в старых, так и в новых версиях платформы.
Начальный релиз обеспечивает поддержку различных типов складных устройств, уже существующих и поступающих на рынок, так что разработчики приложений могут ориентироваться на целые категории аппаратных конфигураций. Ознакомьтесь с обзором в этом блоге и примерами, чтобы узнать больше.
MotionLayout — создание плавной и интерактивной анимации для Android
Обновления существующих библиотек
Навигация
Navigation 2.3 добавляет поддержку динамических функциональных модулей, которые позволяют загружать фрагменты приложения по мере необходимости пользователя, значительно уменьшая начальный размер загрузки. Теперь вы можете перейти к этим модулям так, будто это часть базового APK. Наряду с разрешением параметров запроса, deep link (открытие приложения на устройстве через URL) теперь поддерживает пользовательские действия и типы mime.
WorkManager
В последних версиях WorkManager добавлена поддержка длительной или важной работы, активность которой должна сохраняться операционной системой с помощью foreground service.
Чтобы упростить диагностику проблем с задачами WorkManager, мы добавили новый API, который позволяет заглянуть во внутреннее состояние WorkManager и сохранить его в logcat. Пример результата диагностики WorkManager:
Мы также добавили правила Lint, которые помечают распространенные ошибки при использовании WorkManager, тем самым помогая вам избежать их. Другие обновления API включают в себя: поддержку настройки и наблюдения за промежуточным прогрессом для воркеров, улучшения API-запросов для текущих воркеров и улучшения внутреннего планировщика, используемого для их запуска.
Бенчмарк
Новая альфа-версия библиотеки Benchmark интегрируется с профилированием CPU, так что вы можете профилировать свои бенчмарки, а затем просматривать метод или выборочные трассировки прямо в Android Studio. Мы также добавили поддержку отслеживания распределения памяти, чтобы вы могли оптимизировать время, затрачиваемое на выделение и уменьшить нагрузку от сбора мусора.
Разрешения
Games SDK
Android Games SDK, запущенный ранее в этом году, теперь также является частью Jetpack и доступен в репозитории Google Maven. В настоящее время SDK предлагает Frame Pacing API (API для настройки кадра) и Android Performance Tuner (тюнер производительности Android). Узнайте больше о пакете Games SDK из официальной документации.
CameraX
Существует множество вариаций камер на разных устройствах Android, CameraX работает на 90% из них. С тех пор как CameraX вышла в бета-версию в феврале прошлого года, мы сосредоточились на ее надежности, чтобы обеспечить наилучшее поведение API для широкого спектра устройств. Наша тестовая лаборатория CameraX запускает автоматизированный набор тестов на типах устройств, представляющих более 400 миллионов активных устройств в использовании.
Ознакомьтесь с обширной документацией CameraX и примерами, чтобы узнать больше.
Безопасность
AppCompat
AppCompat обеспечивает адаптацию для различных элементов UI, начиная с темы Material, заканчивая виджетами, такими как Toolbar и темная тема. В последних версиях мы добавили правила Lint, которые позволяют вам лучше понять, какие атрибуты приходят из AppCompat, а какие из фреймворка, и убедиться, что вы используете правильный. Мы также внесли существенные улучшения стабильности в реализацию темной темы AppCompat.
Webkit
Библиотека Webkit Jetpack добавляет новый API в версии 1.2.0, чтобы принудительно использовать темный режим для своего контента. Когда этот API включен, WebView будет отображать сайты в темной теме там, где она поддерживается. При отсутствии поддержки API инвертирует определенные цвета.
Jetpack Compose — новый инструментарий UI Android
Узнайте больше обо всех обновлениях из раздела What’s new in Compose, а затем попробуйте его и дайте нам обратную связь.
Это был краткий обзор всех обновлений Jetpack за последние несколько месяцев. Имея в наличии более 90 библиотек, мы знаем, что может быть трудно найти нужную. Чтобы исправить это, мы переработали веб-страницу Jetpack и добавили, среди прочего, удобный выбор API, чтобы быстро перейти от проблемы, которую вы имеете, к библиотеке Jetpack, которая может ее решить.
Чтобы узнать больше о библиотеках Jetpack, следите за новыми видео, постами в блогах и кодовыми таблицами, выходящими в Jetpack week из 11 недель Android.
Погружение в Jetpack Compose
Всем привет. Перед уходом на выходные спешим поделиться с вами еще одним переводом, подготовленным специально для студентов курса «Android-разработчик. Продвинутый курс».
Пробуем новый UI-фреймворк для Android-приложений
В течение последних нескольких лет, участвуя во многих мобильных проектах, мне приходилось использовать различные технологии, например, такие как Android, ReactNative и Flutter. Переключение с ReactNative обратно на классический Android вызвало у меня смешанные чувства. Возвращение к Kotlin прошло хорошо, но я очень скучал по UI-фреймворку React. Небольшие повторно используемые компоненты, с помощью которых создается пользовательский интерфейс, великолепны и обеспечивают большую гибкость и скорость разработки.
Вернувшись в классический Android, мне нужно было беспокоится о том, чтобы сохранить иерархию View как можно более однообразной. Из-за этого трудно по-настоящему посвятить себя компонентному подходу. Это делает копипаст более заманчивым, что приводит к более сложному и менее поддерживаемому коду. В конечном итоге мы удерживаем себя от экспериментов с пользовательским интерфейсом, которые могли бы улучшить UX.
Android раскрывает Jetpack Compose. Иллюстрация: Эмануэль Багилла (Emanuel Bagilla)
Jetpack Compose спешит на помощь
Поэтому после просмотра What’s new in Android с конференции Google I/O 2019 я сразу же начал разбираться с Compose и постарался больше узнать о нем. Compose — это инструментарий реактивного пользовательского интерфейса, полностью разработанный на Kotlin. Compose выглядит очень похоже на существующие фреймворки пользовательских интерфейсов, такие как React, Litho или Flutter.
Нынешняя структура UI-фреймворка Android существует с 2008 года, и со временем стала более сложной, ее довольно тяжело поддерживать. Jetpack Compose стремится начать все с начала с учетом философии современных компонентов. Фреймворк написан с учетом следующих основных целей:
Простое приложение с Compose: Hello World
Давайте посмотрим на код простого приложения «Hello World» с Jetpack Compose.
Введение состояния
Управление потоком данных и состояниями может быть сложной задачей. Чтобы проиллюстрировать, насколько это легко с Compose, давайте создадим простое приложение-счетчик.
Для работы с состояниями Jetpack Compose использует идеи других современных UI-фреймворков, таких как Flutter и React. Существует однонаправленный и реактивный поток данных, который заставляет ваш виджет обновляться или «перекомпоновываться».
В примере выше мы добавляем кнопки «Add» и «Subtract» вместе с лейблом, отображающим текущее количество нажатий. Как вы можете видеть в примере ниже, обновляя состояние «amount», виджеты разумно перекомпоновываются при изменении состояния.
Запуск демо-приложения
Состояние amount инициализируется с помощью +state < 0 >. Пытаясь выяснить, что это за колдовство, я залез в исходный код. Это мое мнение, хотя я все еще не уверен, что до конца все понимаю.
Пользовательские модели состояний
Вместо использования +state <> для создания модели отдельного значения мы также можем создать пользовательскую модель с помощью аннотации @Model. Мы можем улучшить наше приложение-счетчик, разделив его на более мелкие виджеты и передав модель другим виджетам, которые обновляются и отображают состояние этой модели.
Больше никаких view
Важно понимать, что виджеты Jetpack Compose не используют под капотом view или fragment, это всего лишь функции, которые рисуют на холсте. Плагин Compose Compiler обрабатывает все функции с аннотацией @Composable и автоматически обновляет UI-иерархию.
Layout Inspector инспектирует приложение Jetpack Compose.
Все элементы являются виджетами
Совсем как у Flutter, в Compose все элементы — это виджеты. Более сложные виджеты были разбиты на элементарные виджеты с четкими обязанностями. Поэтому даже padding, spacers и так далее являются виджетами. Например, если вы хотите добавить отступ вокруг кнопки, просто оберните ее в padding виджет:
Соединение кода с пользовательским интерфейсом
Соединять Kotlin-код с UI-виджетами очень легко. Например, если вы хотите показать пользовательский интерфейс, которые повторяется или зависит от каких-то условий. Так, вы можете легко отобразить список имен, как показано ниже.
Это действительно мощная фича, но вы должны быть осторожны, чтобы не запрограммировать слишком много логики на уровне пользовательского интерфейса.
Совместимость с вашими Android-приложениями
Compose разработан таким образом, что вы можете добавить его в уже существующее приложение и постепенно перенести некоторые части вашего UI в новый фреймворк. Приведенные выше примеры добавляют Jetpack Compose UI к одному activity. Также вы можете встроить Compose-виджеты в существующий XML layout с помощью аннотации GenerateView :
Заключение
Я в восторге от Compose, потому что он уменьшает растущие страдания, которую я испытываю при разработке под Android. Он помогает быть более гибким, фокусироваться на создании удобного пользовательского интерфейса, а четкая ответственность также позволяет избежать ошибок.
У Compose впереди долгий путь, на мой взгляд, его можно будет использовать в продакшене не раньше чем через год или два. Тем не менее, я думаю, что сейчас подходящий момент, чтобы взглянуть на Jetpack Compose. Создатели активно ищут фидбек, на этом этапе все еще можно вносить изменения. Все отзывы помогут улучшить этот новый фреймворк.
Прочитайте мою статью «Try Jetpack Compose today», чтобы узнать, как подключить пре-альфа Compose. Также, я думаю, вам очень интересно будет посмотреть видео по шаблонам декларативного интерфейса с Google I/O.
Я с нетерпением жду, когда смогу использовать Compose в реальных Android-приложениях!
Вот и все. Ждем ваши комментарии и отличных всем выходных!
Jetpack Compose — как легко построить UI на Android
В июле этого года вместе с Android Studio Arctic Fox вышла одна из долгожданных библиотек — Jetpack Compose. Она позволяет создавать пользовательский интерфейс в декларативном стиле и обещает быть революцией в построении UI.
Разбираемся, так ли это на самом деле, какие у библиотеки преимущества и недостатки. Подробности — в статье.
Преимущества Jetpack Compose
Jetpack Compose — это набор инструментов для разработки UI в Android-приложении. Он призван ускорить и упростить разработку пользовательского интерфейса, избавить от лишнего кода и соединить модель реактивного программирования с лаконичностью Kotlin.
Сразу с места в карьер — какие есть преимущества у библиотеки:
1. Меньше кода. Jetpack Compose позволяет писать меньше кода, а значит разработчик может больше фокусироваться на проблеме, с меньшим количеством тестов и дебага, а значит и багов.
2. Интуитивно понятный. Compose использует декларативный API — разработчику нужно лишь сказать, что сделать, а все остальное ляжет на плечи библиотеки.
3. Удобство внедрения. Compose совместим с любым существующим кодом. Например, можно вызвать Compose-код из вьюх (view) и, наоборот, вьюхи из Compose. Многие библиотеки вроде Jetpack Navigation, ViewModel и Coroutines уже адаптированы под Compose, что позволяет сравнительно быстро внедрить его в свой код. Кроме того, Android Studio Arctic Fox поддерживает превью создаваемых вьюх.
4. Имеет обширный инструментарий. Jetpack Compose позволяет создавать красивые приложения с прямым доступом к Android Platform API и build-in поддержкой Material Design, тёмной темы, анимаций и других крутых штук.
Далее пройдёмся по основным аспектам библиотеки и посмотрим, как сильно повышается производительность приложения.
Подключение к проекту
Чтобы подключить Jetpack Compose к проекту, необходимо указать некоторые строки кода в своем build.gradle.
В рутовом объявим переменную с версией Compose:
Здесь мы указываем, что в проекте будем использовать Jetpack Compose и объявляем необходимые зависимости (подробнее про зависимости можно почитать в официальном гайде).
Дальше всё просто. В активити (activity) объявлем Composable-функцию, строим иерархию вьюх с указанием необходимых атрибутов и смотрим результат.
Пройдемся по коду. Я написал две реализации вёрсток различной сложности:
1. Простая реализация
Добавляет TextView в вёрстку с текстом с конкатенацией Hello и аргумента, переданного в Greeting.
Важно отметить, что имена Composable-функций начинаются с заглавной буквы. Это соглашение по наименованию функций, поэтому если писать со строчной, то студия будет подсвечивать неверный нейминг.
2. Более сложная реализация
Этот вариант представляет собой скролящийся экран, который содержит изображение, текст и кнопку. Рассмотрим некоторые особенности:
Необходимо объявить Scroll State. Только не обычный, а тот, который позволяет сохранять состояние скролла сквозь рекомпозицию — rememberScrollState().
Column представляет собой ViewGroup с вертикальным расположением элементов.
Modifier позволяет управлять атрибутами, добавлять декорации и поведение к вьюхам.
Остальное интуитивно понятно. И это как раз одна из ключевых особенностей Jetpack Compose — даже если вы не использовали библиотеку ранее, то всё равно с ней разберётесь.
Добавить вьюхи в активити можно через extension setContent <>, например:
В общем-то, создание UI выглядит действительно просто. Теперь определим, насколько сильно оптимизируется приложение и как быстро пользователь увидит окончательный экран.
Для тестирования воспользуемся библиотекой Jetpack Benchmark, о которой, кстати, тоже рассказывали в отдельной статье. Код теста выглядит так:
Протестируем три версии установки вьюхи в активити:
При передаче ресурса в setContentView.
При передаче вьюхи в setContentView.
Итоги тестирования можно посмотреть в таблице: левый столбец — название теста, правый — время на выполнение:
Android, жизненый цикл Jetpack компонентов
Руководство по работе с жизненным циклом Android компонентов, рассмотрим базовые понятия, что такое LifecycleObserver, события и состояния жизненного цикла, кастомные LifecycleOwner.
используется: Kotlin 1.4, Android 10.0, Android Studio 4.2.
В этой статье, вы создадите компонент, учитывающий жизненный цикл (lifecycle-aware компонент), в приложении AwarenessFood. Компонент будет обрабатывать изменения сетевого подключения. Вы также создадите lifecycle owner для обновления состояние сети в Activity.
Само приложение показывает случайный рецепт пользователю и имеет две опции: получить новый случайный рецепт, показать детали связанные с едой. При отключении сети, на главном экране приложения появляется SnackBar с сообщением и кнопкой повтора.
В статье вы изучите:
Жизненные циклы в Android компонентах
Компоненты учитывающие жизненный цикл (Lifecycle-aware components)
Наблюдателей жизненного цикла (Lifecycle observers)
События и состояния
Владельцев жизненного цикла (Lifecycle owners)
Как тестировать Lifecycle-aware компоненты
Статья предполагает, что вы знакомы с основами разработки под Android. Если это не так, посмотрите руководство для начинающих в Android.
Начало
Загрузите материал с оригинальной статьи (кнопка Download вверху страницы здесь). Откройте Android Studio версии 4.2.1 или выше и импортируйте проект.
Ниже общая информация, что делает каждый пакет в проекте:
analytics классы для трекинга событий в приложении
data классы модели
di поддержка зависимостей
monitor содержит единственный класс, который смотрит за состоянием подключения к сети
network классы для доступа к внешним API
repositories классы для доступа к постоянному хранилищу
viewmodels бизнес логика
view экраны
Регистрация в spoonacular API
AwarenessFood приложение получает рецепты через spoonacular API. Вам нужно зарегистрироваться там, чтобы приложение работало правильно.
Заходим на сайт spoonacular.com и создаем новый аккаунт. После подтверждения аккаунта, входим в личный кабинет и ищем там API ключ. Копируем его, открываем файл RecipesModule.kt внутри пакета di и заменяем ключ в следующей строке:
Компилируем и запускаем. Должен появиться экран со случайным рецептом, похожий на такой:
Жмем на кнопку Reload, чтобы загрузить другой случайный рецепт. Если отключить интернет на устройстве и попробовать получить новый рецепт, то появится SnackBar с ошибкой и кнопкой повторить, как на изображении ниже:
Чтобы перейти на экран деталей, жмем в меню More пункт Food Trivia. Вы добавите этот функционал позже. Сейчас это просто экран с кнопкой:
На этом настройка проекта закончена. Сейчас вы готовы познакомиться с компонентами, учитывающие жизненный цикл (lifecycle-aware).
Жизненные циклы в Android
Жизненный цикл Activity:
Для тех, кто хочет узнать побольше о жизненном цикле Activity, взгляните на статью Introduction to Android Activities With Kotlin.
Жизненный цикл Fragment:
Реагируем на изменения жизненного цикла
При таком подходе, ваш код может стать запутанным и подверженным ошибкам. Код внутри методов onStart() и onStop() будет нарастать бесконечно. При этом, легко забыть отписаться от компонента или вызвать метод компонента в неподходящем событии жизненного цикла, что может привести к багам, утечкам памяти и падениям приложения.
Некоторые из этих проблем есть прямо сейчас в приложении. Откройте файл NetworkMonitor.kt в проекте. Этот класс слушает состояние сети и уведомляет Activity об этом.
В MainActivity используется только один компонент, который зависит от жизненного цикла Activity. В более крупных и сложных проектах таких компонентов гораздо больше и это может привести к полному беспорядку.
Используем компоненты жизненного цикла (Lifecycle-Aware)
Владелец жизненного цикла (lifecycle owner) – это компонент имеющий жизненный цикл, такой как Activity или Fragment. Владелец жизненного цикла должен знать все компоненты, которые будут слушать события жизненного цикла. Паттерн «Наблюдатель» считается лучшим подходом для решения такой задачи.
Создание наблюдателя жизненного цикла (lifecycle observer)
Вот и все, теперь это lifecycle наблюдатель. Вы только что сделали первый шаг по превращению NetworkMonitor в lifecycle-aware компонент.
События и состояния жизненного цикла
Lifecycle использует два перечисления для обмена данными о жизненном цикле: Event и State.
Events
Event представляет события жизненного цикла, которые отправляет операционная система:
Каждое значение это эквивалент колбека жизненного цикла. ON_ANY отличается тем, что отправляется при каждом событии (можно сделать один метод для обработки всех событий).
Реакция на события жизненного цикла
Сейчас NetworkMonitor – это LifecycleObserver, но он пока не реагирует на жизненный цикл. Нужно добавить аннотацию @OnLifecycleEvent к методу, чтобы он начал реагировать на конкретное событие.
Добавьте @OnLifecycleEvent к нужным методам, как указано ниже:
Итак, NetworkMonitor теперь получает изменения жизненного цикла, сейчас нужно немного подчистить код. Следующий код больше не нужен в MainActivity.kt, потому что эти действия NetworkMonitor выполняет сам:
Сделав эти изменения в коде, вы переместили из Activity ответственность за инициализацию, регистрацию и освобождение ресурсов в сам компонент.
Состояния (States)
State хранит текущее состояние владельца жизненного цикла. Возможные значения:
Состояния жизненного цикла сигнализируют, что конкретное событие случилось.
Есть прямая связь между событиями и состояниями жизненного цикла. На диаграмме ниже, показана это взаимосвязь:
Эти состояния возникают при:
INITIALIZED: Когда Activity или Fragment уже созданы, но onCreate() еще не вызван. Это первоначальное состояние жизненного цикла.
Используем состояния (State) жизненного цикла
Иногда компоненты должны выполнять код, если их родитель находится, по крайней мере, в определенном состоянии. Нужно быть уверенным, что NetworkMonitor выполняет registerNetworkCallback() в нужный момент жизненного цикла.
Добавьте Lifecycle аргумент в конструктор NetworkMonitor :
С ним у NetworkMonitor будет доступ к состоянию жизненного цикла родителя.
После этого добавьте в код registerNetworkCallback() условие:
Итак, откройте MainActivity.kt и сделайте изменения для NetworkMonitor :
У NetworkMonitor сейчас есть доступ к родительскому жизненному циклу и прослушивание сети запускается только когда Activity находится в нужном состоянии.
Подписка на события жизненного цикла
Чтобы NetworkMonitor действительно начал реагировать на изменения, его родитель должен зарегистрировать NetworkMonitor как слушателя событий. В MainActivity.kt добавьте следующую линию в методе onCreate() после инициализации компонента:
Теперь владелец жизненного цикла будет уведомлять NetworkMonitor об изменениях. Таким же образом можно добавить другие компоненты на прослушивание событий жизненного цикла.
Это отличное улучшение. С помощью одной строчки кода компонент будет получать события жизненного цикла от родителя. Больше не надо писать шаблонный код в Activity или Fragment. Кроме того, компонент содержит весь код инициализации и конфигурации, что делает его самодостаточном и тестируемым.
Соберите и запустите приложение снова. После загрузки рецептов включите «Самолетный режим». Вы увидите ошибку сети в SnackBar, так же как и раньше:
Однако внутреннняя реализация была значительно улучшена.
Кто владеет жизненным циклом?
Все выглядит хорошо, но. кто владеет жизненным циклом? Почему Activity сама владеет жизненным циклом в этом примере? Существуют ли другие владельцы?
Android имеет встроенные компоненты с поддержкой жизненного цикла. Для Activity это ComponentActivity (является базовым классом для AppCompatActivity и реализует интерфейс LifecycleOwner ).
Жизненный цикл Fragment может быть значительно длиннее, чем цикл визуальных компонентов (UI), которых он содержит. Если наблюдатель взаимодействует с UI во Fragment, это может привести к проблемам, поскольку наблюдатель может изменить UI до инициализации или после уничтожения.
Используя этот код, FoodTriviaFragment будет реагировать на события от foodTriviaState (является LiveData ). Так как Fragment является владельцем жизненного цикла ( viewLifecycleOwner ), наблюдатель будет получать обновления данных только, когда Fragment находится в активном состоянии.
Время сделать сборку и запустить приложение. Нажмите More в меню и выберите Food Trivia. Теперь можно получить несколько забавных и интересных Food Trivia в вашем приложении.
Использование ProcessLifecycleOwner
Этот класс представляет жизненный цикл всего процесса приложения. Событие ON_CREATE посылается только один раз, когда приложение стартует. При этом событие ON_DESTROY не будет посылаться вообще.
Важно знать, что эти два последних события произойдут после определенной задержки. ProcessLifecycleOwner должен быть уверен в причине этих изменений. Он отправляет события ON_PAUSE и ON_STOP только если приложение перешло в фоновый режим, а не из-за изменения конфигурации.
Регистрация такого LifecycleObserver происходит немного по-другому. Откройте RecipesApplication.kt и добавьте следующий код в метод onCreate() :
Здесь мы получаем экземпляр ProcessLifecycleOwner и добавляем appGlobalEvents как слушателя событий.
Соберите и запустите приложение. После старта приложения, сверните его в фон. Если открыть LogCat и отфильтровать вывод по тегу APP_LOGGER, то вы должны увидеть сообщения:
Создаем собственного владельца жизненного цикла
Давайте создадим такого владельца, жизненный цикл которого начинается, когда смартфон теряет сетевое соединение и заканчивается при восстановлении соединения.
Откройте UnavailableConnectionLifecycleOwner.kt в пакете monitor и сделайте изменения, чтобы класс поддерживал интерфейс LifecycleOwner :
После этого, добавьте LifecycleRegistry в UnavailableConnectionLifecycleOwner:
Добавляем события
Наконец, добавьте следующий код:
Реакция на события
Теперь откройте MainActivity.kt и добавьте такую строчку кода:
И наконец, замените handleNetworkState() :
Время собрать и запустить ваше приложение. Все работает так же как и раньше, кроме мониторинга сети, где мы используем сейчас кастомный lifecycleOwner для обработки сетевого состояния.
В следующей секции, вы узнаете как тестировать компоненты жизненного цикла.
Тестирование компонентов жизненного цикла
Эти тесты будут проверять, что вызывается нужный метод в NetworkMonitor в соответствии с состоянием владельца жизненного цикла. Чтобы создать тест, нужно пройти те же шаги, что и при создании кастомного владельца жизненного цикла.
Настройка тестов
Здесь используется функционал библиотеки MockK<:target="_blank">, она позволяет имитировать реализацию класса. Аргумент relaxed говорит, что заглушки могут работать без указания их поведения.
После этого создайте переменную:
Этот код добавляет объект LifecycleRegistry в тест, для управления наблюдателями и рассылки им событий жизненного цикла.
И наконец, добавьте следующую строчку кода в метод setup() :
Добавляем тесты
Давайте напишем тест:
Сначала устанавливаете состояние ON_CREATE
Не забудьте импортировать зависимости:
Запускайте тест, он проходит успешно.
Этот код проверяет ON_START событие.
Тест должен пройти успешно.
В конце концов, создадим тест для проверки события ON_STOP и вызова метода unregisterNetworkCallback() :
Этот код проверяет ON_STOP событие.
Добавляем событие ON_START в тест:
Теперь тест проходит успешно.
LiveData: компонент жизненного цикла
К этому моменту вы узнали, как создавать собственный компонент жизненного цикла. Но существуют ли такие же готовые компоненты в Android? Конечно, возможно самый известный из них это LiveData.
Принцип LiveData достаточно прост. Это хранилище данных за которыми можно наблюдать, то есть оно может содержать данные и уведомлять слушателей об изменениях этих данных. Однако LiveData это еще и компонент жизненного цикла, то есть он уведомляет своих наблюдателей только тогда, когда жизненный цикл находится в активном состоянии.
Создание и присваивание переменных LiveData
Откройте MainViewModel.kt из пакета viewmodels. Добавьте там следующие переменные:
Каждый раз, когда LiveData переменная получает новое значение, она уведомляет своих слушателей об изменении. Для установки нового значения используйте поле value.
Давайте изменим метод getRandomRecipe() :
Наблюдения за изменениями LiveData
Откройте MainActivity.kt и добавьте код в метод onCreate() :
В методе observe() есть такой код:
Видно, если LifecycleOwner в состоянии DESTROYED и новое значение было установлено для переменной, то наблюдатель не получит обновление.
Однако, если LifecycleOwner становится активным опять, то наблюдатели получат последнее значение автоматически.
Соберите и запустите проект. Приложение будет показывать прогресс бар во время загрузки приложения, после окончания прогресс бар скрывается.
Поздравляю! Вы отрефакторили проект с использованием компонентов жизненного цикла.
Что посмотреть?
Официальная документация по архитектурным компонентам: Architecture Components: Official Documentation.
Дополнительные материалы по тестированию Jetpack компонентов: Testing Android Architecture Components.