LifeCycle

LifeCycle is a component that can sense changes in the LifeCycle of the host. Common hosts include activities/fragments, services, and applications. LifeCycle holds information about the host’s LifeCycle state and notifies observers listening to the host when the host’s LifeCycle changes.

LifeCycle arises primarily to address the coupling between the LifeCycle of system components and ordinary components.

  • System components include activities, fragments, services, and Applications.
  • Common components: components that encapsulate code in terms of function or function.

In what cases is the life cycle of a system component coupled to the life cycle of a normal component?

Here’s an example:

There is a business need for video playback in the 58 tribe business. We need to initialize the video component in the Activity, stop the video in the onPause() method, and reclaim the video component and some resources in the onDestroy() method. Doing so is tedious and makes the coupling between the page and the components higher.

This is the kind of problem that LifeCycle can fully solve. It not only reduces the degree of coupling between modules, but also reduces the possibility of memory leaks.

(2) Use of LifeCycle

Jetpack provides us with two interfaces:

Observed: LifecycleOwner

Observer: LifecycleObserver

The listening system component needs to implement the LifecycleOwner interface, and the observer needs to implement the LifecycleObserver interface.

Use Scenario 1: Use LifeCycle to decouple pages from components

(1) Decouple activities

Step 1: Add dependencies

implementation 'androidx. Appcompat: appcompat: 1.2.0'
Copy the code

In AndroidX ComponentActivity already implements the LifecycleOwner interface by default. If the project does not migrate to AndroidX, the Support library will still be used. The new SDK also implements the LifecycleOwner interface through SupportActivity.

In the LifecycleOwner interface, there is only one getLifecycle method.

Step 2: Implement the observer

If we want to listen to the lifecycle of an Activity, all we need to do is customize the component and implement the LifecycleObserver interface. This interface has no interface methods and does not require any specific implementation.

For example, take the video just played:

  1. Create a MyVideoPlayListener class that implements the LifecycleObserver interface, and do all the video playing-related logic in this class. Methods in the component that need to be notified when the Activity Lifecycle changes are marked with the @onlifecycleEvent (lifecyc.event.on_xxx) annotation so that when the Activity Lifecycle changes, The marked method is automatically called.
public class MyVideoPlayListener implements LifecycleObserver {
    private static String TAG = "MyVideoPlayListener";

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    private void initVideo(a){
        Log.d(TAG,"initVideo");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    private void startPlay(a){
        Log.d(TAG,"startPlay");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    private void pausePlay(a){
        Log.d(TAG,"pausePlay"); }}Copy the code

2. Reference MyVideoPlayListener in MainActivity.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyVideoPlayListener listener = newMyVideoPlayListener(); getLifecycle().addObserver(listener); }}Copy the code

(2) Decouple fragments

In the new VERSION of the SDK, fragments also implement the LifecycleOwner interface by default, so the above example applies to fragments as well.

Scenario 2: Use LifecycleService to decouple services from components

(1) LifecycleService Basic introduction

In addition to activities/fragments, a very important component that has a lifecycle in Android is a Service. LifecycleService is used to listen to and decouple Service components.

public class LifecycleService extends Service implements LifecycleOwner {

    private final ServiceLifecycleDispatcher mDispatcher = new ServiceLifecycleDispatcher(this); .@Override
    @NonNull
    public Lifecycle getLifecycle(a) {
        returnmDispatcher.getLifecycle(); }}Copy the code

(2) The specific use method

Step 1: Add related dependencies

implementation "Androidx. Lifecycle: lifecycle - service: 2.2.0." "
Copy the code

Step 2: Create the MyServiceObserver class to implement the LifecycleObserver interface. Use the @onlifecyCleEvent tag for methods you want to get called synchronously when the Server lifecycle changes.

public class MyServiceObserver implements LifecycleObserver {
    private static String TAG = "MyServiceObserver";

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    private void initVideo(a){
        Log.d(TAG,"initVideo");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private void pausePlay(a){
        Log.d(TAG,"stopPlay"); }}Copy the code

Step 3: Create a MyService class that inherits from LifecycleService. Because LifecycleService is a direct subclass of Service, it is used no differently than a normal Service.

public class MyService extends LifecycleService {
    private MyServiceObserver myServiceObserver;
    
    public MyService(a){
        myServiceObserver = newMyServiceObserver(); getLifecycle().addObserver(myServiceObserver); }}Copy the code

Usage scenario 3: Use ProcessLifecycleOwner to listen for the life cycle of an application

In addition to activities, fragments, and services, components that have lifecycles include applications. ProcessLifecycleOwner is used to listen for the entire application lifecycle.

Specific use method:

Step 1: Add dependencies

implementation "Androidx. Lifecycle: lifecycle - process: 2.2.0." "
Copy the code

Step 2: Define an ApplicationObserver that implements the LifecycleObserver interface.

public class ApplicationObserver implements LifecycleObserver {
    private String TAG = this.getClass().getName();

    /** * will only be called once */ during the lifetime of the application
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void onCreate(a) {
        Log.d(TAG,"Lifecycle.Event.ON_CREATE");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onStart(a) {
        Log.d(TAG,"Lifecycle.Event.ON_START");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume(a) {
        Log.d(TAG,"Lifecycle.Event.ON_RESUME");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause(a) {
        Log.d(TAG,"Lifecycle.Event.ON_PAUSE");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onStop(a) {
        Log.d(TAG,"Lifecycle.Event.ON_STOP");
    }

    /** * will never be called, the system will not distribute the call ON_DESTROY event */
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy(a) {
        Log.d(TAG,"Lifecycle.Event.ON_DESTROY"); }}Copy the code

Step 3: Associate ApplicationObserver in Application.

public class App extends Application {
    @Override
    public void onCreate(a) {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(newApplicationObserver()); }}Copy the code

Notes:

  1. ProcessLifecycleOwner is listening for the entire application, regardless of the number of activities.
  2. Lifecycle. Event.on_create will be called only once and Lifecycle. Event.on_destroy will never be called.
  3. There will be a delay in calling Lifecycle. Event.on_pause and Lifecycle. Event.on_stop because the system needs to allow time for “screen rotation, Activity re-creation due to configuration changes”.

There are two other ways of writing LifeCycle

LifeCycle can be implemented in three ways:

  1. LifecycleObserver cooperate@OnLifecycleEventannotations
  2. DefaultLifecycleObserver hosts all life cycle events
  3. LifecycleEventObserver encapsulates host Lifecycle events as lifecyc.event

In the previous usage introduction, we used the first approach: LifecycleObserver with the @onlifecyCleEvent annotation.

This is easy to use, but it is better to add lifecycle compiler as an annotation handler, or use reflection to call back to the corresponding method at runtime:

annotationProcessor "Androidx. Lifecycle: lifecycle - compiler: 2.2.0." "
Copy the code

With this annotation handler, methods marked with @onlifecyCleEvent can no longer be declared private, or the following error will be reported:

method marked with OnLifecycleEvent annotation can not be private
Copy the code

Here are two other implementations:

DefaultLifecycleObserver hosts all life cycle events

Using DefaultLifecycleObserver requires using Java8, we first add a dependency:

Implementation "androidx lifecycle: lifecycle - common - java8:2.2.0." "Copy the code

Then in the build.gradle at the module level add:

android {
  ...
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}
Copy the code

With the lifecycle common-Java 8 dependency, the lifecycle compiler dependency can be removed.

There are six lifecycle methods in the DefaultLifecycleObserver interface:

public interface DefaultLifecycleObserver extends FullLifecycleObserver {

    @Override
    default void onCreate(@NonNull LifecycleOwner owner) {}@Override
    default void onStart(@NonNull LifecycleOwner owner) {}@Override
    default void onResume(@NonNull LifecycleOwner owner) {}@Override
    default void onPause(@NonNull LifecycleOwner owner) {}@Override
    default void onStop(@NonNull LifecycleOwner owner) {}@Override
    default void onDestroy(@NonNull LifecycleOwner owner) {}}Copy the code

This interface inherits from the FullLifecycleObserver, which we cannot use directly to own all of the hosted lifecycle events due to permission issues.

So, we need to override the lifecycle methods that our business needs to listen to by implementing the DefaultLifecycleObserver interface.

(2) LifecycleEventObserver hosts Lifecycle events encapsulated as lifecyc.event

// Override the onStateChanged method, inside the method, by implementing the LifecycleEventObserver interface
// Implement specific business logic by determining Lifecycle.Event
public class MyVideoPlayObserver implements LifecycleEventObserver {
    private static String TAG = "MyVideoPlayObserver";

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        switch (event){
            case ON_CREATE:
                Log.d(TAG,"initVideo");
                break;
            case ON_START:
                Log.d(TAG,"startPlay");
                break;
            case ON_RESUME:
                Log.d(TAG,"resumePlay");
                break;
            default:
                 break; }}}Copy the code

How to choose these three implementations?

DefaultLifecycleObserver and LifecycleEventObserver are recommended.

  1. Java8 uses a DefaultLifecycleObserver to implement Lifecycle and Java7 uses annotations. The annotated approach will be deprecated once Java8 becomes mainstream on Android.
  2. If a class implements both the DefaultLifecycleObserver interface and the LifecycleEventObserver interface, then the methods in the DefaultLifecycleObserver will fire first, The LifecycleEventObserver’s onStateChanged method is then executed.
  3. If a class implements the DefaultLifecycleObserver interface, it also uses the@OnLifecycleEventAnnotation, then the annotation mode is automatically ignored.

Four,

The main purpose of LifeCycle components is to help us decouple them so that the components we define can also feel the LifeCycle changes.

Five, the complement

As of this release, the latest version of lifecycle_version is 2.2.0. If you need to obtain the latest version, please check the official website:

Developer. The android. Google. Cn/jetpack/and…

The lifecycle-Extensions API is deprecated. If one of the tools available at lifecycle needs to be used, add a dependency:

    dependencies {
        def lifecycle_version = "2.2.0"
        def arch_version = "2.1.0."

        // ViewModel
        implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
        // LiveData
        implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
        // Lifecycles only (without ViewModel or LiveData)
        implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

        // Saved state module for ViewModel
        implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"

        // Annotation processor
        annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
        // alternately - if using Java8, use the following instead of lifecycle-compiler
        implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

        // optional - helpers for implementing LifecycleOwner in a Service
        implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"

        // optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
        implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"

        // optional - ReactiveStreams support for LiveData
        implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"

        // optional - Test helpers for LiveData
        testImplementation "androidx.arch.core:core-testing:$arch_version"
    }
    
Copy the code

6. Reference materials

Official Google Jetpack documentation

Moocs: Learn Jetpack from an architect

The Android Jetpack App Guide by Ye Kun