В этом уроке рассмотрим возможности Lifecycle. Как подписаться на его события. Как узнать текущее состояние Activity.
Полный список уроков курса:
- Урок 1. Lifecycle
- Урок 2. LiveData
- Урок 3. LiveData. Дополнительные возможности
- Урок 4. ViewModel
- Урок 5. Room. Основы
- Урок 6. Room. Entity
- Урок 7. Room. Insert, Update, Delete, Transaction
- Урок 8. Room. Query
- Урок 9. Room. RxJava
- Урок 10. Room. Запрос из нескольких таблиц. Relation
- Урок 11. Room. Type converter
- Урок 12. Room. Миграция версий базы данных
- Урок 13. Room. Тестирование
- Урок 14. Paging Library. Основы
- Урок 15. Paging Library. PagedList и DataSource. Placeholders.
- Урок 16. Paging Library. LivePagedListBuilder. BoundaryCallback.
- Урок 17. Paging Library. Виды DataSource
- Урок 18. Android Data Binding. Основы
- Урок 19. Android Data Binding. Код в layout. Доступ к View
- Урок 20. Android Data Binding. Обработка событий
- Урок 21. Android Data Binding. Observable поля. Двусторонний биндинг.
- Урок 22. Android Data Binding. Adapter. Conversion.
- Урок 23. Android Data Binding. Использование с include, ViewStub и RecyclerView.
- Урок 24. Navigation Architecture Component. Введение
- Урок 25. Navigation. Передача данных. Type-safe аргументы.
- Урок 26. Navigation. Параметры навигации
- Урок 27. Navigation. NavigationUI.
- Урок 28. Navigation. Вложенный граф. Global Action. Deep Link.
- Урок 29. WorkManager. Введение
- Урок 30. WorkManager. Критерии запуска задачи.
- Урок 31. WorkManager. Последовательность выполнения задач.
- Урок 32. WorkManager. Передача и получение данных
- Урок 33. Практика. О чем это будет.
- Урок 34. Практика. TodoApp. Список задач.
- Урок 35. Практика. TodoApp. Просмотр задачи
Довольно часто часть логики приложения завязана на жизненный цикл Activity. Мы включаем что-либо в методах onStart или onResume и выключаем в onPause или onStop.
Рассмотрим пример.
У нас есть какой-то класс для работы с сервером. Он должен взаимодействовать с сервером, пока Activity открыто. Соответственно, мы будем подключать его к серверу при показе Activity и отключать при скрытии Activity.
public class MyServer { public void connect() { // ... } public void disconnect() { // ... } }
Метод connect используется для подключения к серверу, disconnect - для отключения.
Вызываем эти методы в onStart и onStop в Activity.
@Override protected void onStart() { super.onStart(); myServer.connect(); } @Override protected void onStop() { super.onStop(); myServer.disconnect(); }
Теперь MyServer будет подключен пока Activity видимо на экране.
Это вполне классическая, часто используемая схема. И в простом примере все выглядит неплохо. Но в сложных приложениях содержание методов onStart, onStop и пр. может состоять из нескольких десятков строк и быть достаточно запутанным. Гугл рекомендует выносить эту логику из Activity. Давайте посмотрим, как это можно сделать.
Lifecycle
У Activity есть метод getLifecycle, который возвращает объект Lifecycle. На этот объект можно подписать слушателей, которые будут получать уведомления при смене lifecycle-состояния Activity.
Activity и фрагменты в Support Library, начиная с версии 26.1.0 реализуют интерфейс LifecycleOwner. Именно этот интерфейс и добавляет им метод getLifecycle.
Т.е. у вас должна быть такая строка в build.gradle файле модуля, в секции dependencies
implementation 'com.android.support:appcompat-v7:26.1.0'
Либо используйте более свежую версию.
В нашем примере слушателем будет MyServer. Чтобы иметь возможность подписаться на Lifecycle, он должен наследовать интерфейс LifecycleObserver.
public class MyServer implements LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_START) public void connect() { // ... } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) public void disconnect() { // ... } }
Обратите внимание, что интерфейс LifecycleObserver пустой. В нем нет кучи методов типа onStart, onStop и т.п. Мы просто помечаем в классе MyServer его же собственные методы аннотацией OnLifecycleEvent и указываем, при каком lifecycle-событии метод должен быть вызван.
В нашем примере, мы указываем, что метод connect должен вызываться в момент onStart, а метод disconnect - в момент onStop.
Осталось подписать экземпляр MyServer на Lifecycle.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // ... getLifecycle().addObserver(myServer); }
В Activity методом getLifecycle получаем Lifecycle, и методом addObserver подписываем myServer.
А методы onStart и onStop в Activity нам больше не нужны, их можно удалить.
Теперь, при переходе Activity из состояния CREATED в состояние STARTED, его объект Lifecycle вызовет метод myServer.connect. А при переходе из STARTED в CREATED - Lifecycle вызовет myServer disconnect.
При этом в Acivity это потребовало от нас минимум кода - только подписать myServer на Lifecycle. Все остальное решает сам MyServer.
На схеме ниже вы можете увидеть какие состояние проходит Activity и какие события при этом вызываются.
Ничего нового тут для нас нет, все это азы Android. Тут вы можете видеть состояния и события. Они связаны очень просто - при переходе между состояниями происходят события.
Эти события мы указывали в аннотациях OnLifecycleEvent к методам объекта MyServer.
Полный список событий можно посмотреть в документации.
Отписаться от Lifecycle можно методом removeObserver.
Any
Вы можете использовать событие ON_ANY для получения всех событий в одном методе
@OnLifecycleEvent(ON_ANY) void onAny(LifecycleOwner source, Lifecycle.Event event) { // ... }
В этом случае все события будут вызывать этот метод.
Используйте входящий параметр event, чтобы определить, какое именно событие произошло
Состояние
Если вы хотите узнать текущее состояние Activity, то у его объекта Lifecycle есть метод getCurrentState:
if (getLifecycle().getCurrentState() == Lifecycle.State.RESUMED) { // ... }
Полный список состояний можно посмотреть в документации.
Также, вы можете проверить, что текущее состояние Activity не ниже определенного состояния.
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) { // ... }
Метод isAtLeast здесь проверяет, что состояние Activity не ниже, чем STARTED. Т.е. либо STARTED, либо RESUMED.
Присоединяйтесь к нам в Telegram:
- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance
- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня