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

в 17:06, , рубрики: android, android architecture components, architecture, development, lifecycle, LifecycleActivity, LifecycleFragment, LifecycleObserver, LifecycleRegistry, LifecycleService, ProcessLifecycleOwner, Разработка под android, разработка приложений

image
Как я уже упоминал в предыдущем материале, компонент 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, которому как параметр передается интересуещее нас событие.

@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
   void stateUpdated() {
      //будет вызваться при каждом изменении состояния жизненого цикла у овнера.
   }

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 и берет всю работу по поддержке на себя, нам лиш нужно создать его экземпляр.

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

public class MyFragment extends Fragment implements LifecycleRegistryOwner {
    LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
    @Override
    public LifecycleRegistry getLifecycle() {
       return lifecycleRegistry;
    }
}

В пакете 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, константа с какого будет передаваться в конструктор и потом использоваться чтоб отличить владельца по логам:

public class SomeObserver implements LifecycleObserver {
   private Owner owner;
   public SomeObserver(Lifecycle lifecycle, Owner owner) {
      this.owner = owner;
      lifecycle.addObserver(this);
   }
   @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
   void onCreate() {
      Log.d(«Observer», owner + «: onCreate»);
   }
   @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
   void onStop() {
      Log.d(«Observer», owner + «: onStop»);
   }
   enum Owner {
      ACTIVITY, FRAGMENT, PROCESS, SERVICE
   }
}

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

Листинг LifecycleActivity:

public class MainActivity extends LifecycleActivity {
   SomeObserver someObserver = new SomeObserver(getLifecycle(), SomeObserver.Owner.ACTIVITY);
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      Log.d(«Owner», «onCreate»);
      setContentView(R.layout.activity_main);
   }
   @Override
   protected void onStop() {
      super.onStop();
      Log.d(«Owner», «onStop»);
}
}

Листинг LifecycleFragment:

public class MyFragment extends LifecycleFragment {
   SomeObserver someObserver = new SomeObserver(getLifecycle(), SomeObserver.Owner.FRAGMENT);
  
   public MyFragment() {
   }
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
 Bundle savedInstanceState) {
      return inflater.inflate(R.layout.<i>fragment_my</i>, container, false);
   }
}

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

public class MyService extends LifecycleService {
   SomeObserver someObserver;
   @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
      someObserver = new SomeObserver(getLifecycle(), SomeObserver.Owner.SERVICE);
      final Handler handler = new Handler();
      handler.postDelayed(new Runnable() {
         @Override
         public void run() {
            stopSelf();
         }
      }, 5000);
      return super.onStartCommand(intent, flags, startId);
}
}

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

public class CustomApplication extends Application {
   private SomeObserver processObserver;
   @Override
   public void onCreate() {
      super.onCreate();
      processObserver = new SomeObserver(ProcessLifecycleOwner.get().getLifecycle(), SomeObserver.Owner.PROCESS);
      Intent intent = new Intent(this, MyService.class);
      startService(intent);
}
}

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

Также полезные ссылки:

developer.android.com/reference/android/arch/lifecycle/package-summary.html

developer.android.com/topic/libraries/architecture/lifecycle.html

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

Автор: Юрий

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js