What is the service lifecycle in android

Android Architecture Components. Часть 2. Lifecycle

Как я уже упоминал в предыдущем материале, компонент Lifecycle призван упростить работу с жизненным циклом, а имено избежать калбеков с Activity/Fragment в наш компонент, который должен реагировать на события жизненого цикла. В этой статье, мы подробно разберем как он устроен и как с ним работать.

Сам компонент состоит из классов: Lifecycle, LifecycleActivity, LifecycleFragment, LifecycleService, ProcessLifecycleOwner, LifecycleRegistry. Интерфейсов: LifecycleOwner, LifecycleObserver, LifecycleRegistryOwner.

Lifecycle — класс, который хранит информацию про состояние жизненного цикла и разрешает другим объектам отслеживать его c помощью реализации LifecycleObserver. Состоит из методов: addObserver(LifecycleObserver), removeObserver(LifecycleObserver) и getCurrentState(). Как понятно из названий для добавления подписчика, удаления и соответственно получения текущего состояния.

Для описания состояния есть два enum. Первый Events — который обозначает изменение цикла и второй State — который описывает текущее состояние.

Events — повторяет стадии жизненного цикла и состоит из ON_CREATE, ON_RESUME, ON_START, ON_PAUSE, ON_STOP, ON_DESTROY, а также ON_ANY который информирует про изменения состояния без привязки к конкретному этапу. Отслеживание изменений цикла происходит с помощью пометки метода в обсервере аннотацией OnLifecycleEvent, которому как параметр передается интересуещее нас событие.

State — состоит из следующих констант: INITIALIZED, CREATED, STARTED, RESUMED, DESTROYED. Для получения состояния используеться метод getCurrentState() из Lifecycle. Также в Enum State реадизован метод itAtLeast(State), который отвечает на вопрос являтся State выше или равным от переданого как параметр.

Для работы с компонентом Lifecycle, нам нужно определить owner, то есть владельца жизненного цикла и observer, того кто на него будет подписан. У owner может быть любое количество подписчиков, также стоит отметить что observer будет проинформирован про изменение состояния, еще до того как у owner будет вызван метод super() на соответствующий метод жизненного цикла.

Owner должен реализовывать интерфейс LifecycleOwner, который содержит один метод getLifecycle(), который возвращает екземпляр класса холдера Lifecycle.

Observer должен реализовать интерфейс маркер LifecycleObserver.

Для самостоятельного обьявления кастомной Activity/Fragment, как owner-а, которые еще не поддерживают новый компонент и соответственно не имеют реализации Lifecycle, созданы: класс LifecycleRegistry и интерфейс LifecycleRegistryOwner.

Интерфейс LifecycleRegistryOwner, который в свою очередь расширяет интерфейс LifecycleOwner с единственым отличием в том что метод getLifecycle() возвращает LifecycleRegistry вместо Lifecycle.

Класс LifecycleRegistry, который являеться расширением Lifecycle и берет всю работу по поддержке на себя, нам лишь нужно создать его экземпляр.

Вот как выглядит реализация:

В пакете android.arch.lifecycle приведено 4 реализации owner: LifecycleActivity, LifecycleFragment, LifecycleService, ProcessLifecycleOwner.

LifecycleActivity — это FragmentActivity c реализацией LifecycleRegistryOwner. Является временным решением для упрощения работы и как сказано в документации будет пока Lifecycle не будет интегрирован с support library.

LifecycleFragment — это Fragment c пакета support.v4, который также как и в случае с LivecycleActivity реализовывает LifecycleRegistryOwner и является временным решением.

LifecycleService — это Service, который является также LifecycleOwner.

ProcessLifecycleOwner — это класс, который представляет Lifecycle всего процесса. Этот класс будет полезен если вам нужно отслеживать уход приложения в бэкграунд или возврат его на передний план.

Для того чтоб, связать owner и observer нужно у owner вызвать getLifecycle().addObserver(LifecycleObserver) Ниже я продемонстрирую работу всех этих классов. Для демонстрации, я создал класс SomeObserver, который будет логировать вызовы ON_CREATE и ON_STOP, я его буду использовать для всех видов owner-ов, поэтому для упрощения я добавил enum, константа с которого будет передаваться в конструктор и потом использоваться, чтоб отличить владельца по логам:

В целом же работа со всеми классами аналогичная, все что нам нужно это создать экземпляр обсервера и подписать его на Lifecycle, в моей реализации мы передаем наш Lifecycle в конструктор обсервера, подпиской занимаеться уже сам обсервер. Данный подход, является всего лишь делом вкуса и не более.

Листинг LifecycleService, он отрабатывает 5 секунд и завершается, его я запускаю из Application:

И для ProcessLifecycleOwner я решил расширить Application, как можно заметить ProcessLifecycleOwner сделан как singleton и являеться абсолютно самостоятельным компонентом:

Полный листинг вы можете посмотреть по линке: here

Также полезные ссылки: раз и два.

В следующей статье мы более подробно разберем LiveData компонент.

Источник

Understanding the Application Lifecycle in Android

Before getting started, please hold on a minute and count the number of mobile applications present in your mobile phone. Tired of counting the number of Android apps on your phone? Yeah, this is common for all the Android users. We have applications for almost everything that we do in our daily life. But you are an Android developer and your way of looking on to the Android apps should be different from that of a regular Android user. You should know each and everything about the life of a particular Android app. You must know the Application life cycle of the app that you are making for your users. If you don’t have the proper understanding of the life cycle of your mobile application then no doubt, there will not be any effect on the working of the application but this will give a bad impression of your app on your users. Want to know how? Be with us.

Читайте также:  Тесты для антивирусов для андроид

In this blog, we will look upon the Android Application life cycle. We will try to find how this will affect the user experience. So, let’s get started.

Android Application life cycle

Android is a perfect example of true multi-tasking i.e. you can perform more than one tasks at a particular instant of time. Actually, we are not performing multiple tasks at a particular instant of time, rather it seems that we are performing more than one tasks at a time. In a very simple way, at any particular instant of time, only one app can be in the running state and other apps will be in the background state. All these processes are managed and handled in such a way that it seems that we are doing more than one task at some instant of time.

But the problem that arises here is that, a particular Android device has some limited amount of space and processing speed, and in order of have a fluent flow or to provide a fluent use of all the applications, to give a better experience to the users, Android pushes the application that is least used in some cache. By doing so, the app that is not being used for a longer period of time, will be pushed in the background and possibly it’s onStop() method will be called to stop the activity of that app.

LRU Cache

LRU or Least Recently Used Cache is the cache used by the Android OS to push the applications that are least used in the nearer time. For example, if you are running the music app along with the Email, Facebook, Instagram, and Whatsapp application then the app which you have not used for a long time will be placed at the header or the front of the cache and the application that is used recently will be put in the back of the LRU cache queue.

For example, if the Email app is least used and the Facebook app is the most used app in the mobile phone at a particular time, then the Email app will be placed on the front of the queue of the LRU cache and the Facebook app will be placed at the back of the LRU cache queue.

Also, if the application is restarted or opened again, then it will be placed at the back of the LRU cache queue. For example, if you open the Email app again, then that Email app will be placed at the back of the LRU cache, not at the front of the LRU cache.

Priorities of Android Application

So far, we have seen that, in order to have a proper memory and battery management in the Android device, Android pushes or kills the applications that are having less priority. In order to free up some space from the Android device, Android uses some sets of rules and assign priorities to the applications based on the current running states of the applications. Following are the process status that are associated with the Android Application:

Note: Priorities are ranked in a higher to lower fashion

  1. Foreground process: A process is said to be in the foreground state if a user interacts with that process. For example, if you are watching some video on the YouTube app, then the YouTube app will be called to be in the foreground state because that app is currently being used by the user. So, the applications that are on the foreground have the highest priority.
  2. Visible process: A process is said to be in the visible state when the activity of the application can be visible but not in the fort. 🙂 Confusing? Let’s have an example, whenever you are using some application that requires some kind of permission then you are using the visible process. For instance, let’s take the example of Instagram application, when you want to upload some images from your device then the app will ask you to give permission of the storage. At this time, your Instagram activity is visible but not in the foreground because, in the foreground, you are having the permission box asking for storage permission.
  3. Service process: A process is said to be a Service process if it is currently running but it does not come under the above two categories i.e. the foreground and the visible process. This is helpful for those applications that perform some background task such as downloading some data or uploading some data. One example of the service process is the uploading of files in Google drive where uploading of files is done in background.
  4. Background process: A process is said to be in background state if it’s onStop() method is being called by the Android. Suppose you are using some application and you suddenly press the home button of your mobile then at that time, your application will go to the background state from the foreground state. Also, the application will be placed in the LRU cache so that it will be called whenever the user reopens the app. This is done so because starting from scratch is very difficult as compared to start from an intermediate state.
  5. Empty process: A process is said to be in the empty state if it doesn’t come under the category of the above four mentioned process states. In an empty process, there is no active component of the application i.e. each and every component of the process will the in stop state. The application can be put in the LRU for better caching purpose but is memory is not present or low in amount, then that application will be removed from the cache also.
Читайте также:  Share google contacts android

Why consider Application life cycle?

In the very beginning of the blog, I told you that if you don’t have the knowledge of the Application life cycle, then the working of the app will not be affected but the user’s experience will be bad. Hold on! So, why we have learned the Application life cycle if it doesn’t affect the working of our app?

Before answering the question, I would like to request you all to open the Power Usage of your mobile by the mobile applications present in your phone.

You can see that apart from the Android system, at a particular instant of time, the Hotstar app which is a video streaming app used 12.1% of the total battery. Also, the YouTube app, which is again a video streaming app used 4.7% of the total battery available. This is because both these apps use some kind of data transport over the Internet and the battery is being used to establish, maintain and disconnect the service.

What if your app takes or uses a lot of battery? Will it be preferred by the users to use your app? The answer is no. While making an android application, you should handle each and every application state of the Android app.

For example, if you are using some data receiving and sending operation in your app and you want to manage and hold the session whenever the app is running then you should handle the operations that are to be done when your application will be in the background state. If your application is in the background state then you should not hold the session because this will result in more resource utilization and this, in turn, will use more battery and memory. So, in the onPause() state, you should release the session and in the onResume() state, you should again build and session and do the rest operations.

By doing so, your application will have a good impact on your users and your users will recommend the app to their friends. So, Android application life cycle is very important to make an Android application.

Conclusion

In this blog, we learned the Application life cycle in Android. We saw how different states can affect the working of Android apps on our phone. We also saw how we can make use of application life cycle to make an app that builds a great impression on the user and will help you to make an app that can be reached to billions of users.

Источник

Android Lifecycle-aware Architecture Components

6 ноября 2017 года компания Google опубликовала информацию об анонсе стабильной версии
архитектурных компонентов. Разработчики Google предоставили руководство по архитектуре приложений и представили ряд классов и интерфейсов, которые упрощают создание приложений с выстроенной архитектурой, облегчают присоединение новых программистов к проекту и уменьшают порог вхождения в мир взрослой разработки для тех людей, которые только начали программировать под систему Android.

Представленные компоненты для работы с жизненным циклом Android можно сравнить со скрытым от глаз часовым механизмом. Всего пара строчек кода и все работает. Но как все устроено? Да и вообще, стоит ли использовать архитектурные компоненты в своих домашних проектах или даже в проектах с сотнями тысяч активных установок?

Lifecycle, lifecycle-aware components and activities

Жизненный цикл — очень важный пункт в мире андроид разработки, которому зачастую уделяется недостаточно внимания. По этой причине у пользователей могут происходить ошибки в работе приложения. Например, при телефонном звонке приложение может завершить работу с критической ошибкой. Это происходит из-за пересоздания активити и необработанного сохранения состояния.

Частично проблемы пересоздания активити можно избежать. Например, запретить пересоздание — поставить в манифесте настройку активити android:screenOrientation=«portrait». Но это решит проблемы только с пересозданием активити во время изменения конфигурации (например, смены ориентации экрана). Проблему того, что в какой-то момент операционной системе не хватит памяти и она уничтожит процесс с исполняемой активити этот способ не решает. Вернувшись к работе с приложением, первое, что увидит пользователь — критическую ошибку.

Читайте также:  2гис для андроида gps

Так или иначе разработчику нужно позаботиться об обработке состояний жизненного цикла. На помощь приходят lifecycle-aware components. Архитектурные компоненты имеют стабильную версию 1.0 и их можно применять в production-разработке приложений.

Плюсы и минусы использования lifecycle-aware components

Рассмотрим практические плюсы и минусы использования компонентов.

Плюсов несомненно больше

  1. подключение нового сотрудника к команде разработки приложения. Все android разработчики знают и умеют пользоваться официальными библиотеками от компании Google. Не надо тратить время на обучение локальным решениям для поддержания архитектуры;
  2. меньше кода при разработке фичи;
  3. стабильность работы компонентов;
  4. улучшение стабильности работы приложения после внедрения компонентов.

Минусы

  1. время на ознакомление с компонентами и добавление в проект;
  2. добавился код для сопровождения архитектуры при разработке новой функции, но этот минус легко решается генерацией кода. Хорошие статьи на эту тему здесь и здесь.

Как работать с lifecycle-aware components?

Начиная с Support Library версии 26.1.0 фрагменты и активити из коробки реализуют интерфейс LifecycleOwner. Этот интерфейс имеет только один метод — getLifecycle().
Чтобы добавить наблюдателя за событиями жизненного цикла достаточно всего лишь в классе-наблюдателе реализовать интерфейс LifecycleObserver и написать в активити/фрагменте

И все? Да, для разработчика на этом работа заканчивается. Достаточно в коде наблюдателя пометить нужные методы аннотациями и реагировать на события жизненного цикла.

Интересный факт, что одной и той же аннотацией можно пометить несколько методов и все они будут вызваны при изменении состояния жизненного цикла.

Что же скрывается за парой строчек, как все работает, какие есть нюансы?
Найдем ответы на перечисленные ниже вопросы на примере фрагмента.

Что возвращает фрагмент, реализуя интерфейс LifecycleOwner в методе getLifecycle()? Описание основных методов

Фрагмент имплементирует интерфейс LifecycleOwner, реализуя метод getLifecycle(): Lifecycle.

Lifecycle — абстрактный класс, определяющий объект, как объект имеющий жизненный цикл Android.

Реализация данного класса LifecycleRegistry берет на себя всю работу по контролю за добавлением, удалением наблюдателей, обработкой событий жизненного цикла, сообщением об изменениях жизненного цикла всем наблюдателям.

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

То есть если LifecycleOwner находится в состоянии Lifecycle.State.STARTED при добавлении LifecycleObserver, то последний получит два события Lifecycle.Event.ON_CREATE и Lifecycle.Event.ON_START.

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

Удаление наблюдателя из списка наблюдающих происходит в методе.

Если удаление наблюдателя происходит во время изменения состояния жизненного цикла и отправка события об изменении состояния вызвана после удаления — наблюдатель не получит данного события.

Если в наблюдателе несколько методов ожидают одно событие и хотя бы один из методов был вызван во время удаления наблюдателя из списка наблюдащих, то все остальные методы также будут вызваны и только после этого произойдет удаление.

Возврат текущего состояния по запросу.

В любой момент можно запросить текущее состояние жизненного цикла и, опираясь на ответ, предпринять какие-либо действия. Метод вернет экземпляр перечисления State.

Существуют следующие виды State

INITIALIZED — данное состояние соответствует тому времени, когда сущность реализующая интерфейс LifecycleOwner создана, но метод onCreate() еше не был вызван.

CREATED — данное состояние активно после вызова метода onCreate() и до вызова onStop().

STARTED — данное состояние активно после вызова метода onStart() и до вызова onPause().

RESUMED — данное состояние наступает после вызова метода onResume().

DESTROYED — данное состояние наступает непосредственно перед вызовом onDestroy(). По наступлению этого состояния LifecycleOwner более не отправляет событий об изменении состояний.

Что происходит при добавлении наблюдателя к списку наблюдающих?

При вызове метода lifecycle.addObserver(observer) observer помещается в конструктор экземпляра класса-обертки ObserverWithState. Как понятно из названия класса — этот класс хранит observer с последним обработанным состоянием жизненного цикла. Изначально устанавливает состояние DESTROYED или INITIALIZED.

После создания экземпляра наблюдателя с последним обработанным состоянием жизненного цикла — пытаемся добавить наблюдателя в коллекцию FastSafeIterableMap методом putIfAbsent().

Если метод возвращает какой-то элемент — значит он уже есть в коллекции и добавлять повторно не надо. Что и происходит далее в коде. Работа метода addObserver() в случае имеющегося observer’а в списке прекращается. Также работа прекращается в том случае, если lifecycleOwner == null.

Происходит вычисление текущего состояния жизненного цикла и начинают отправляться события до тех пор, пока состояние хранящееся в наблюдателе меньше текущего.

Что же за upEvent(state: State)? Замечу также, что существует downEvent(state: State). В зависимости от того, что сейчас происходит с жизненным циклом, опираясь на текущее состояние можно определить какое событие надо отправлять наблюдателю.

Разобраться с этим просто, посмотрев на тело методов и на схему, приведенные ниже.

Как LifecycleOwner сообщает LifecycleObserver’у о событиях, происходящих с жизненным циклом фрагмента?

Фрагмент, реализующий интерфейс LifecycleOwner, содержит ряд доступных для вызова методов, соответствующих событиям жизненного цикла: такие как performCreate(savedInstanceState: Bundle), performStart(), performStop() и другие.

Класс FragmentManagerImpl вызывает данные методы, во фрагменте в свою очередь вызываются соответствующие методы onStart, onStop и прочие. А также вызываются методы класса LifecycleRegistry.

В классе LifecycleRegistry вычисляется состояние, о котором надо отправить следующее событие на основе принятого события.

И после этого вычисляется какой тип события надо отправить наблюдателю — upEvent(state: State) или downEvent(state: State)

Источник

Оцените статью