Why Lifecycle is used

In application development, code related to the life cycle of Activity or Fragment components is unavoidable. Because most application components defined in the Android framework have a life cycle.

The lifecycle is managed by the framework code running in the operating system or process. They are at the heart of how Android works, and apps must follow them. Failure to do so can cause memory leaks and even application crashes.

Write a listener in the Activity and call this listener in the Activity’s different lifecycle methods

class MainActivity : AppCompatActivity() {

    private lateinit var myListener: MyListener
    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        myListener = MyListener(this)}override fun onStart(a) {
        super.onStart()
        myListener.start()
    }

    override fun onResume(a) {
        super.onResume()
        myListener.resume()
    }

    class MyListener(content: Context){
        fun start(a){}
        fun resume(a){}}}Copy the code

In real development, multiple components may call back in the Activity lifecycle, which may require a lot of code in the Activity lifecycle methods, making them difficult to maintain.

In addition to the above issues, in practice you need to ensure that a component starts before an Activity or Fragment stops. This may not be possible if you do time-consuming operations in the component.

Lifecycle can help solve these problems

Two, basic use

Lifecycle dependency introduction

dependencies {
    def lifecycle_version = "xxx"
    def arch_version = "xxx"

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

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

    // Annotation processor
    kapt "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-ktx:$lifecycle_version"

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

Copy the code

Lifecycle is a class that stores information about the Lifecycle state of a component, such as an Activity or Fragment, and allows other objects to observe that state.

Lifecycle tracks the Lifecycle state of its associated components using two main enumerations:

  1. Events: Lifecycle events dispatched from the framework and Lifecycle classes.

    These events map to callback events in activities and fragments

  2. State: The current state of the component tracked by Lifecycle object.

The simple summary is:

A class can monitor the Lifecycle state of a component by adding annotations to its methods and then adding an observer by calling the addObserver() method of the Lifecycle class and passing an instance of the observer

Lifecycle is simple to use

Create a lifecycle observer

class MyObserver: LifecycleObserver {

    companion object{
        const val TAG = "MyObserver"
    }

    // Use annotations to indicate that the method needs to listen for the specified lifecycle events
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate(a){
        Log.d(TAG,"onCreate")}@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun connectListener(a) {
        Log.d(TAG,"resume")}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun disconnectListener(a) {
        Log.d(TAG,"onPause")}@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun destroy(a){
        Log.d(TAG,"onDestroy")}}Copy the code
  • First create a class and implement itLifecycleObserverinterface
  • Use it in a method@OnLifecycleEventAnnotations make the method lifecycle aware, and the parameters in parentheses indicate the lifecycle events to listen for

Lifecycle tracks the Lifecycle State of the associated component primarily through the two enumerated classes Event and State.

Lifecycle 2.4.0 removes Lifecycle awareness through annotations for reasons that will be discussed later.

Observe the life cycle

Complete the binding of Lifecycle and LifecycleObserver in the Activity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        lifecycle.addObserver(MyObserver())
    }
}
Copy the code
  1. ActivityinheritedAppCompatActivityAnd its parent classComponentActivityIt’s implemented by defaultLifecycleOwnerinterface
  2. throughgetLifecycle()Method returns one directlyLifecycleObject that can be passed by the objectaddObserver()Method will beLifecycleWith the specifiedLifecycleObserverTo bind

If you inherit from a normal Activity Lifecycle cannot be obtained directly using the getLifecycl() method and you need to implement the LifecycleOwner interface yourself.

2.2 Customizing LifecycleOwner

If you inherit from a normal Activity, you need to customize the LifecycleOwner interface.

LifecycleOwner is a single method interface that indicates that a class has Lifecycle.

public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle(a);
}
Copy the code

The LifecycleObserver implementation component works seamlessly with the LifecycleOwner implementation class, whose owner provides the lifecycle, and observers can register to observe the lifecycle.

The customLifecycleOwnerimplementation

class FirstActivity:Activity(),LifecycleOwner {

    private lateinit var mLifecycleRegistry: LifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        mLifecycleRegistry = LifecycleRegistry(this)
        lifecycle.addObserver(MyObserver())
        mLifecycleRegistry.currentState = Lifecycle.State.CREATED
    }

    override fun onStart(a) {
        super.onStart()
        mLifecycleRegistry.currentState = Lifecycle.State.STARTED

    }

    override fun onDestroy(a) {
        super.onDestroy()
        mLifecycleRegistry.currentState = Lifecycle.State.DESTROYED
    }

    override fun onPause(a) {
        super.onPause()
        mLifecycleRegistry.currentState = Lifecycle.State.STARTED
    }

    override fun getLifecycle(a): Lifecycle {
        return mLifecycleRegistry
    }
}
Copy the code

2.3 ProcessLifecycleOwner

Use ProcessLifecycleOwner to get the status of the application before and after switching (remember to introduce the lifecycle-process dependency)

implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
Copy the code

The usage is similar to that of an Activity

class MyApplication : Application() {
    fun onCreate(a) {
        super.onCreate()
        // Register the App lifecycle Observer
        ProcessLifecycleOwner.get().lifecycle.addObserver(ApplicationLifecycleObserver())
    }

    /** * Application lifecycle observation, which provides the lifecycle of the entire Application process * function: listen for the Application to enter the foreground or background */
    private class ApplicationLifecycleObserver : LifecycleObserver {
        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        private fun onAppForeground(a) {
            Log.w(TAG, "ApplicationObserver: app moved to foreground")}@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        private fun onAppBackground(a) {
            Log.w(TAG, "ApplicationObserver: app moved to background")}}}Copy the code
  1. Lifecycle.Event.ON_CREATEIt’s only going to be distributed once,Lifecycle.Event.ON_DESTROYWill not be distributed.
  2. The first oneActivityTo enter,ProcessLifecycleOwnerWill dispatchLifecycle.Event.ON_START.Lifecycle.Event.ON_RESUME.
  3. Lifecycle.Event.ON_PAUSE.Lifecycle.Event.ON_STOPAnd will be in the last oneActivitPost-exit post-delay distribution.
  4. This delay is sufficient if the activity is destroyed and recreated due to configuration changesProcessLifecycleOwnerNo events are sent.

Lifecycle 2.4.0The version removes the lifecycle awareness through annotations

Three, principle analysis

Lifecycle 2.4.0 is based on Lifecycle 2.4.0 and demo is based on SDK 31

Before learning the core principles of Lifecycle, there are a few core roles that Lifecycle needs to understand briefly:

  • Lifecycle

    A class that holds information about a component’s life-cycle state, such as an Activity or Fragment, and allows other objects to observe that state.

  • LifecycleOwner

    Lifecycle C. The class that implements this interface holds a Lifecycle object, and changes to the Lifecycle object are observed by its registered observer LifecycleObserver and trigger its corresponding events

  • LifecycleObserver

    Lifecycle observer; Classes that implement this interface can be registered by the LifecycleOwner class’s addObserver() method. Once registered, LifecycleObserver can observe LifecycleOwner lifecycle events.

  • LifycycleRegistry

    Lifecycle is an abstract class whose only implementation class is LifecycleRegistry.

  • .

Lifecycle will be implemented as follows:

The main implementation classes are as follows:

The principle of **Lifecycle can be summed up simply as ** :

  1. AppCompatActivityTo achieve theLifecycleOwnerInterface, itsgetLifecycle()Method returnLifecycleThe object ofLifecycleRegistry
  2. AppCompatActivityBy default, a none is mountedUIOf the interfaceFragmenttheFragmentIt can be obtained in different ways according to the system version number of the user’s phoneAppCompatActivityEvent change notification, final callLifecycleRegistryhandleLifecycleEvent()Method will beLifecycle.EventPay it forward. At this point,LifecycleRegistryJust got theLifecycle.Event
  3. LifecycleRegistryIt’s going to pass through the outsideaddObserverincomingLifecycleObserverObjects are wrapped asObserverWithStateThe inside of the classLifecycleEventObserverObject, which blocks incoming messages from outsideLifecycleObserverThe differences (which could be interfaces or annotations)
  4. LifecycleRegistryBy directly callingObserverWithStateThe inside of the classLifecycleEventObserverThe object’sonStateChangedMethod to complete the final event callback. This completes the process

3.1 ReportFragment

Activities generally inherit from AppCompatActivity.

// Inherits an Activity class file for AppCompatActivity

lifecycle.addObserver(MyObserver())
Copy the code

The getLifecycle() method clicks into the ComponentActivity, which returns a LifecycleRegistry object

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
    LifecycleOwner.ViewModelStoreOwner.SavedStateRegistryOwner.OnBackPressedDispatcherOwner {

    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); .public Lifecycle getLifecycle(a) {
        returnmLifecycleRegistry; }}Copy the code

ComponentActivity implements the LifecycleOwner interface. GetLifecycle () returns an instance of a LifecycleRegister object.

LifecycleRegistry is the only implementation class for Lifecycle, and LifycycleOwner is the holder of Lifecycle.

Take a look at the LifecycleOwner class first

public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle(a);
}
Copy the code

Lifecycle is an abstract class with three methods (add an observer, remove an observer, get the current state) and enumeration definitions of states

public abstract class Lifecycle {
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    @NonNull
    AtomicReference<Object> mInternalScopeRef = new AtomicReference<>();
    
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);
    
    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);
    
    @MainThread
    @NonNull
    public abstract State getCurrentState(a);
    
    @SuppressWarnings("WeakerAccess")
     public enum Event {
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_ANY
     }
    
     @SuppressWarnings("WeakerAccess")
    public enum State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0; }}... }Copy the code

The relationship between Event and State is shown as follows:

Here are some of the ReportFragment’s most useful features.

Take a look at the onCreate() method for ComponentActivity

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {... ReportFragment.injectIfNeededIn(this);
    if(mContentLayoutId ! =0) { setContentView(mContentLayoutId); }}Copy the code

OnCreate () for ComponentActivity injects a ReportFragment through the injectIfNeededIn() static method. If you know the ReportFragment life cycle, you can know the Activity life cycle and then inform relevant observers.

Take a look at the ReportFragment implementation

public class ReportFragment extends android.app.Fragment {
    public static void injectIfNeededIn(Activity activity) {
        / / if it is Android, 10 or more registerActivityLifecycleCallbacks ways to realize the lifecycle callback
        if (Build.VERSION.SDK_INT >= 29) {
            LifecycleCallbacks.registerIn(activity);
        }
        // Before API29, add an invisible Fragment to the Activity to get the correct callback to the Activity's life cycle events
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            // Add the Fragment to the Activity
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            // Hopefully, we are the first to make a transaction.manager.executePendingTransactions(); }}}Copy the code

The ReportFragment injectIfNeededIn() function distributes events in two cases

  • The system version of the running device must be less than 29.

    This situation indirectly gets callback notifications for the Activity’s various life cycle events by adding a ReportFragment without a UI to the Activity

  • The system version of the running device must be 29 or greater.

    This case registers a LifecycleCallbacks with the Activity to get callback notifications directly for each lifecycle event. The operations in the first case are also performed

InjectIfNeededIn (), according to two situations for dispatching events. This is because registerActivityLifecycleCallbacks is 29 when android SDK app. The new method of adding the Activity, Getting event notifications directly from LifecycleCallbacks is supported starting with this release.

SDK>=29In the case

Event distribution via LifeCycleCallbacks. When the onCreate, onStart, and onResume methods of the Activity class are called, the corresponding Event value is sent through the dispatch() method. An Event value is sent before onPause, onStop, and onDestroy are called

@RequiresApi(29)
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {

    static void registerIn(Activity activity) {
        activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
    }

    @Override
    public void onActivityCreated(@NonNull Activity activity,
                                  @Nullable Bundle bundle) {}@Override
    public void onActivityPostCreated(@NonNull Activity activity,
                                      @Nullable Bundle savedInstanceState) {
        dispatch(activity, Lifecycle.Event.ON_CREATE);
    }

    // omit some similar code...@Override
    public void onActivityPreDestroyed(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_DESTROY);
    }

    @Override
    public void onActivityDestroyed(@NonNull Activity activity) {}}Copy the code
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
    if (activity instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
        return;
    }

    if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceofLifecycleRegistry) { ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); }}}Copy the code

Once the Dispatch () method gets the Event value, Lifecycle object is obtained via the activity. The LifecycleRegistry object is then retrieved through type determination, and the Event value is finally passed by calling the handleLifecycleEvent() method to notify the outside world of each lifecycle Event.

SDK<29In the case

The ReportFragment lifecycle itself is associated with the Activity in which it resides. Indirectly get callback notifications of Activity lifecycle events by calling dispatch() within the corresponding ReportFragment lifecycle function to send the corresponding Event value

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    / /...
    dispatch(Lifecycle.Event.ON_CREATE);
}

@Override
public void onStart(a) {
    super.onStart();
    / /...
    dispatch(Lifecycle.Event.ON_START);
}

@Override
public void onDestroy(a) {
    super.onDestroy();
    dispatch(Lifecycle.Event.ON_DESTROY);
    / /...
}
Copy the code
private void dispatch(@NonNull Lifecycle.Event event) {
    if (Build.VERSION.SDK_INT < 29) { dispatch(getActivity(), event); }}Copy the code

The dispatch() function internally determines whether or not the Event value is actually distributed based on the target device version number, avoiding duplicate sending with LifecycleCallbacks when SDK version number is greater than 29

In this case, The ReportFragment uses the above logic to forward the Event value of the Activity

ProcessLifecycleOwnerimplementation

At this point it becomes clear how the outside world gets the Activity’s life cycle events. What is not clear about ProcessLife lifecycle awareness, however. Let’s move on to the ReportFragment lifecycle related methods here

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    dispatchCreate(mProcessListener);
    dispatch(Lifecycle.Event.ON_CREATE);
}

@Override
public void onStart(a) {
    super.onStart();
    dispatchStart(mProcessListener);
    dispatch(Lifecycle.Event.ON_START);
}

private void dispatchCreate(ActivityInitializationListener listener) {
    if(listener ! =null) { listener.onCreate(); }}...Copy the code

The ReportFragment calls methods such as dispatchCreate() and dispatch() in the lifecycle method.

Where is mProcessListener set up

public class ReportFragment extends android.app.Fragment {
    interface ActivityInitializationListener {
        void onCreate(a);
        void onStart(a);
        void onResume(a); }}Copy the code
public class ProcessLifecycleOwner implements LifecycleOwner {
    private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);

    / / the Activity monitor
    ActivityInitializationListener mInitializationListener =
        new ActivityInitializationListener() {
        @Override
        public void onCreate(a) {}

        @Override
        public void onStart(a) {
            activityStarted();
        }

        @Override
        public void onResume(a) { activityResumed(); }};// Singleton implements the ProcessLifecycleOwner object
    private static final ProcessLifecycleOwner sInstance = new ProcessLifecycleOwner();

    void attach(Context context) {
        mHandler = new Handler();
        // Distribute the ON_CREATE event
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        Application app = (Application) context.getApplicationContext();
        app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
            @RequiresApi(29)
            @Override
            public void onActivityPreCreated(@NonNull Activity activity,
                                             @Nullable Bundle savedInstanceState) {
                activity.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
                    @Override
                    public void onActivityPostStarted(@NonNull Activity activity) {
                        activityStarted();
                    }

                    @Override
                    public void onActivityPostResumed(@NonNull Activity activity) { activityResumed(); }}); }@Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                if (Build.VERSION.SDK_INT < 29) { ReportFragment.get(activity).setProcessListener(mInitializationListener); }}@Override
            public void onActivityPaused(Activity activity) {
                activityPaused();
            }

            @Override
            public void onActivityStopped(Activity activity) { activityStopped(); }}); }// When the first Activity is created, the Lifecycle.event.ON_START Event is distributed
    void activityStarted(a) {
        mStartedCounter++;
        if (mStartedCounter == 1 && mStopSent) {
            mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
            mStopSent = false; }}}Copy the code
  1. ProcessLifecycleOwnerTo the wholeAppprovidelifecycle, through which we can observe the entire application life cycle
  2. inattach()In theregisterActivityLifecycleCallbacks()Registers a listener as soon as there isActivityCreate and set one to itListener, guaranteed everyReportFragmentOne of themListener.
  3. ProcessLifecycleOwnerIs a global singleton, and can listen to the entire application life cycle, needs to be initialized at the beginning, must be inContentProviderIt’s initialized inside

Follow ProcessLifecycleOwner init () method calls, came to the ProcessLifecycleOwnerInitializer

public final class ProcessLifecycleInitializer implements Initializer<LifecycleOwner> {

    @NonNull
    @Override
    public LifecycleOwner create(@NonNull Context context) {
        LifecycleDispatcher.init(context);
        ProcessLifecycleOwner.init(context);
        returnProcessLifecycleOwner.get(); }... }Copy the code

The LifecycleDispatcher initialization method is found here, so let’s take a closer look at the whole method

class LifecycleDispatcher {

    private static AtomicBoolean sInitialized = new AtomicBoolean(false);

    static void init(Context context) {
        if (sInitialized.getAndSet(true)) {
            return;
        }
        // Register a listener
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
    }

    @SuppressWarnings("WeakerAccess")
    @VisibleForTesting
    static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {

        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            // Inject a ReportFragment
            ReportFragment.injectIfNeededIn(activity);
        }

        @Override
        public void onActivityStopped(Activity activity) {}@Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}}private LifecycleDispatcher(a) {}}Copy the code

Therefore, any Activity in the application will be injected with a ReportFragment

Summary:

  1. AppCompatActivityTo achieve theLifecycleOwnerInterface, itsgetLifecycle()Method returnLifecycleThe object ofLifecycleRegistry.LifecycleRegistryisLifecycleThe unique implementation class of
  2. ComponentActivitytheonCreate()Is injected intoReportFragmentIf you knowReportFragmentYou can know the Activity’s life cycle and then inform the relevant observers. Different notification operations are performed according to the version.
  3. ProcessLifecycleOwnerTo achieve theLifecycleOwnerTo observe the entire application life cycle. It is a global singleton inContentProvidertheonCreate()In the initialization

3.2 LifecycleRegister

As you can see from the ReportFragment logic above, when Lifecycle.Event is passed out, the handleLifecycleEvent() method of the LifecycleRegistry object is called. So how does it forward the Event value to LifecycleObserver?

LifecycleRegistry is the only implementation class for Lifecycle that implements specific event callbacks and state management.

Take a look at the LifecycleRegistry internal implementation.

public class LifecycleRegistry extends Lifecycle {
    // Current state
    private State mState;
     // Hold a weak reference to LifecycleOwner to avoid memory leaks
    private final WeakReference<LifecycleOwner> mLifecycleOwner;
    
    public LifecycleRegistry(@NonNull LifecycleOwner provider) {
        this(provider, true);
    }

    private LifecycleRegistry(@NonNull LifecycleOwner provider, boolean enforceMainThread) {
        mLifecycleOwner = newWeakReference<>(provider); mState = INITIALIZED; mEnforceMainThread = enforceMainThread; }... }Copy the code

LifecycleRegistry internally holds a weak reference to LifecycleOwner. An external Observer can be added to LifecycleRegistry via the addObserver() method. The Activity may be destroyed before the time-consuming operation is completed. So LifecycleRegistry holds a weak reference to LifcycleOwner rather than a strong reference to avoid memory leaks.

addObserverInternal implementation

We typically add an observer via addObserver() to take a look at the internal implementation

//Lifecycle adds the @mainThread annotation to the addObserver method. There is no need to consider multithreading
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    enforceMainThreadIfNeeded("addObserver");
    Lifecycle state is not DESTROYED. Lifecycle state is set to the initial state
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    // construct ObserverWithState, i.e. ObserverWithState. This state is used to determine whether the observer has been notified when a new event is triggered and all observers are notified
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    // Add observer objects and statefulObserver objects to the FastSafeIterableMap data structure
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    if(previous ! =null) {
        // An observer cannot join the same Lifecycle more than once. If the Observer has been passed in before, it is not added again and returns directly
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        // If the LifecycleOwner object has already been reclaimed, it is returned directly
        return;
    }

    // Check whether the add is reentrant. Normally this flag is always false
    //mAddingObserverCounter ! = 0. This happens because the developer added a LifecycleObserver first, and while the event was being called back to it, called the addObserver method in the callback method to add a new LifecycleObserver
    booleanisReentrance = mAddingObserverCounter ! =0 || mHandlingEvent;
    // Calculate the current Lifecycle state
    State targetState = calculateTargetState(observer);
    // Add one to indicate that you are currently in the process of calling back the Event value to the newly added LifecycleObserver
    mAddingObserverCounter++;
    Migrate the newly added Observer to its current state. For example, if the current state is RESUMED, the Observer will receive the ONCREATE ONSTART ONRESUME event
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        // Save the current state value mState that the Observer has traversed
        pushParentState(statefulObserver.mState);
        final Event event = Event.upFrom(statefulObserver.mState);
        if (event == null) {
            throw new IllegalStateException("no event up from " + statefulObserver.mState);
        }
        statefulObserver.dispatchEvent(lifecycleOwner, event);
        / / remove mState
        popParentState();
        targetState = calculateTargetState(observer);
    }

    if(! isReentrance) { sync(); } mAddingObserverCounter--; }Copy the code

The main logic of the addObserver() function is:

  1. Computes the initial state, if currentLifecycleState not forDESTROYED, we set it to the initial state
  2. Will the incomingobserverObject wrapped asObserverWithStateTo determineobserverHas been added tomapIn the data
  3. If not added tomap, calculate the currentLifecycletheState, through the loop check mode toObserverWithStateGradually issuedEventvalue

Take a look at the ObserverWithState class

static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        // Pass the Observer to Lifycycling for type wrapping
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) { State newState = event.getTargetState(); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; }}Copy the code

ObserverWithState passes LifecycleObserver objects passed to Lifecycling for type packing.

Lifecycling’s type wrapping is to consolidate both the reflection logic and the interface callback logic into a new LifecycleEvening Server object, unifying the Event distribution process into a single entry.

3.3 Event Distribution

LifecycleRegistry’s handleLifecycleEvent(Lifecycle.Event) method is called by the ReportFragment when Lifecycle. The method converts the corresponding State value based on the Event value received, updates the local mState, notifes all observers of the Event, and finally calls the dispatchEvent method with ObserverWithState.

@SuppressWarnings("deprecation")
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
    if (activity instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
        return;
    }

    if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceofLifecycleRegistry) { ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); }}}public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    enforceMainThreadIfNeeded("handleLifecycleEvent");
    moveToState(event.getTargetState());
}

private void moveToState(State next) {
    if (mState == next) {
        return;
    }
    mState = next;
    if(mHandlingEvent || mAddingObserverCounter ! =0) {
        mNewEventOccurred = true;
        // we will figure out what to do on upper level.
        return;
    }
    mHandlingEvent = true;
    sync();
    mHandlingEvent = false;
}
Copy the code

LifecycleRegistry eventually calls sync() to synchronize the lifecycle to all observers.

private void sync(a) {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                                        + "garbage collected. It is too late to change lifecycle state.");
    }
    // Loop over all observers
    while(! isSynced()) {// Check whether all observers are synchronized.
        mNewEventOccurred = false;
        Younger (the oldest observer) and newest (the newest observer) in the mObserverMap; determine whether the current state is forward or backward, e.g., from STARTED to RESUMED is RESUMED, and vice versa
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            // Distribute events backwards
            backwardPass(lifecycleOwner);
        }
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if(! mNewEventOccurred && newest ! =null
            && mState.compareTo(newest.getValue().mState) > 0) {
            // Forward distribute events
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}
Copy the code

The main contents of the Sync method are as follows:

  1. First, judge whether all observers are in state synchronization. If not, a state comparison is performed
  2. The currentLifecycletheStateAnd all theObservertheStateCompare, judge and executebackwardpassorforwardPassMethods.

Look at the isSynced() and forwardPass() methods

private boolean isSynced(a) {
    if (mObserverMap.size() == 0) {
        return true;
    }
    State eldestObserverState = mObserverMap.eldest().getValue().mState;
    State newestObserverState = mObserverMap.newest().getValue().mState;
    return eldestObserverState == newestObserverState && mState == newestObserverState;
}
Copy the code
private void forwardPass(LifecycleOwner lifecycleOwner) {
    // Get an iterator in the order of adding an Observer
    Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
        mObserverMap.iteratorWithAdditions();
    // Iterate over all observers
    while(ascendingIterator.hasNext() && ! mNewEventOccurred) { Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next(); ObserverWithState observer = entry.getValue();// If the State of the current Observer is less than mState, increment the current State
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            // Increment the current state
            final Event event = Event.upFrom(observer.mState);
            if (event == null) {
                throw new IllegalStateException("no event up from " + observer.mState);
            }
            // Distribute eventsobserver.dispatchEvent(lifecycleOwner, event); popParentState(); }}}Copy the code

ForwardPass () method:

  1. First get a press addObserverSequential iterators, and then iterate over all of themObserver
  2. For eachObserver, increments its state and passesdispatchEventDistributes life cycle events until their state is incremented toLifecyclethemStateSo far.

State synchronization and event distribution for all observers is accomplished in this way.

The aforementioned observer is an ObserverWithState object

static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        // Pass the Observer to Lifycycling for type wrapping
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) { State newState = getStateAfter(event); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; }}public interface LifecycleEventObserver extends LifecycleObserver {
    
    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
Copy the code

LifecycleRegistry will wrap all lifecycleObservers that are passed in externally into LifecycleEventObserver objects according to Lifecycling. Why is this required?

  • LifecycleEventObserverFullLifecycleObserverIt’s all inherited fromLifecycleObserverInterface, developers themselves implement customObserverIt might implement both or either of these interfaces,LifecycleRegistryAll interface methods that exist must be called back when an event is triggered
  • In addition to implementing callbacks through interface methods, Google also provides a way to implement callbacks through annotations, in which case you need to implement callbacks through reflection

For this reason, LifecycleRegistry classes would be very bloated if they performed type judgments, interface callbacks, reflection calls, and other operations directly on external observers.

So Lifecycling’s role is to encapsulate this set of logic, and simply opening a onStateChanged method will allow LifecycleRegistry to complete the event distribution, making the process much clearer and more accountable

Look at the lifecycleEventObserver() method for Lifecycling

static LifecycleEventObserver lifecycleEventObserver(Object object) {
    boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
    boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
    / / if the object at the same time inherited LifecycleEventObserver and FullLifecycleObserver, will forward its packaging for FullLifecycleObserverAdapter object to events
    if (isLifecycleEventObserver && isFullLifecycleObserver) {
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
                                                (LifecycleEventObserver) object);
    }
    if (isFullLifecycleObserver) {
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
    }

    if (isLifecycleEventObserver) {
        // Object is already the desired target type (LifecycleEventObserver), just return as is
        return (LifecycleEventObserver) object;
    }

    // Classes generated by APT
    finalClass<? > klass = object.getClass();// Check whether the sClassToAdapters Map has XXX_LifecycleAdapter
    int type = getObserverConstructorType(klass);
    if (type == GENERATED_CALLBACK) {
        // Get the klass-related collection from the Map
        List<Constructor<? extends GeneratedAdapter>> constructors =
            sClassToAdapters.get(klass);
        if (constructors.size() == 1) {
            // Create objects according to the XXX_LifecycleAdapter constructor
            GeneratedAdapter generatedAdapter = createGeneratedAdapter(
                constructors.get(0), object);
            / / then created object encapsulation in SingleGeneratedAdapterObserver object
            return new SingleGeneratedAdapterObserver(generatedAdapter);
        }
        GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
        for (int i = 0; i < constructors.size(); i++) {
            adapters[i] = createGeneratedAdapter(constructors.get(i), object);
        }
        return new CompositeGeneratedAdaptersObserver(adapters);
    }
    return new ReflectiveGenericLifecycleObserver(object);
}
Copy the code

The lifecycleEventObserver() method determines the type of the Object that is passed in and builds the corresponding Adapter Object that is returned.

If the incoming LifecycleObserver realized LifecycleEventObserver interface and FullLifecycleObserver interface at the same time, it is constructed as a FullLifecycleObserverAdapter object and return

If the incoming LifecycleObserver realized LifecycleEventObserver interface and FullLifecycleObserver interface at the same time, it is constructed as a FullLifecycleObserverAdapter object and return

If the incoming LifecycleObserver only FullLifecycleObserver interface, it is constructed as a FullLifecycleObserverAdapter object and return

If the callback function is called from a class generated by the annotation handler, It returns a SingleGeneratedAdapterObserver/CompositeGeneratedAdaptersObserver object (both realized LifecycleEventObserver interface, The difference is the number of observers that send events to the Observer when the lifecycle state changes.)

If none of the above conditions are met, each callback function is called by reflection. Returns a ReflectiveGenericLifecycleObserver object

When customizing LifecycleObserver with annotations, traditionally annotations have to be parsed through reflection, which has a performance impact. On the one hand, we use caching to avoid getting the constructor through reflection every time. On the other hand, through the annotation processor, at compile time to those by @onlifecycleEvent annotation of the ordinary method, preprocessing, generation to “class name _LifecycleAdapter” named class, will be a variety of callback methods directly logical conversion, avoid reflection, and then improve performance.

3.4 Dependency Injection

When introducing the lifecycle added statements annotationProcessor “androidx. Lifecycle: lifecycle – compiler: $lifecycle_version”, this is the annotation processor dependent

MyObserver_LifecycleAdapter (MyObserver_LifecycleAdapter)

public class MyObserver_LifecycleAdapter implements GeneratedAdapter {
  final MyObserver mReceiver;

  MyObserver_LifecycleAdapter(MyObserver receiver) {
    this.mReceiver = receiver;
  }

  @Override
  public void callMethods(LifecycleOwner owner, Lifecycle.Event event, boolean onAny,
      MethodCallsLogger logger) {
    booleanhasLogger = logger ! =null;
    if (onAny) {
      return;
    }
    if (event == Lifecycle.Event.ON_CREATE) {
      if(! hasLogger || logger.approveCall("onCreate".1)) {
        mReceiver.onCreate();
      }
      return;
    }
    if (event == Lifecycle.Event.ON_START) {
      if(! hasLogger || logger.approveCall("onStart".1)) {
        mReceiver.onStart();
      }
      return;
    }
    if (event == Lifecycle.Event.ON_RESUME) {
      if(! hasLogger || logger.approveCall("onResume".1)) {
        mReceiver.onResume();
      }
      return;
    }
    if (event == Lifecycle.Event.ON_PAUSE) {
      if(! hasLogger || logger.approveCall("onPause".1)) {
        mReceiver.onPause();
      }
      return;
    }
    if (event == Lifecycle.Event.ON_STOP) {
      if(! hasLogger || logger.approveCall("onStop".1)) {
        mReceiver.onStop();
      }
      return;
    }
    if (event == Lifecycle.Event.ON_DESTROY) {
      if(! hasLogger || logger.approveCall("onDestroy".1)) {
        mReceiver.onDestroy();
      }
      return; }}}Copy the code

Since our events are declared in MyObserver method annotations, fetching these things every time we go to reflection takes a lot of performance. So we use the dependency library to preprocess these marked methods, and then directly call back these methods to avoid reflection and improve performance

LifecycleEventObserver approach for the analysis of the discovery, because MyObserver_LifecycleAdapter only one constructor, then can construct SingleGeneratedAdapterObserver, While SingleGeneratedAdapterObserver internal is actually call the method

class SingleGeneratedAdapterObserver implements LifecycleEventObserver {

    private final GeneratedAdapter mGeneratedAdapter;

    SingleGeneratedAdapterObserver(GeneratedAdapter generatedAdapter) {
        mGeneratedAdapter = generatedAdapter;
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        mGeneratedAdapter.callMethods(source, event, false.null);
        mGeneratedAdapter.callMethods(source, event, true.null); }}Copy the code

The mGeneratedAdapter above is actually our MyObserver_LifecycleAdapter.

The life cycle starts with the Activity, then ReportFragment, and finally the observer that we define.

3.5 summarize

Lifecycle is used and parsed as described above, but there are a few things to note when using Lifecycle:

  1. LifecycleStateful backflow, that is, registration in any lifecycleLifecycleObservertheLifecycleObserverAll previous lifecycle callbacks are executed until they are synchronized with the lifecycle state at registration time.
  2. inActivity/FragmentWhen a lifecycle method is overridden, the corresponding method of the parent class must be called becauseLifecycleIs distributed in the parent class’s corresponding lifecycle method
  3. LifecycleObserverIs the one usedMapTo save it, thoughLifecycleObserverisMaptheKeyBut also as aList<Pair<LifecycleObserver,xxx>>To exist, that is to say, is fundamentally aListBut the sameObserverYou can only save one, if oneLifecycleObserverbeaddTwice, the lifecycle method will only call back once.

4. Common problems

4.1 @ OnLifecycleEvent abandoned

Lifecycle 2.4.0 deprecated the @onlifecycleEvent annotation and LifecycleEventObserver or DefaultLifecycleObserver is recommended instead.

Lifecycle is used with annotations as described earlier. Why use annotations? Why scrap it again?

There are many types of lifecycle events, and without annotations, all methods need to be implemented, resulting in code bloat

interface FullLifecycleObserver extends LifecycleObserver {

    void onCreate(LifecycleOwner owner);

    void onStart(LifecycleOwner owner);

    void onResume(LifecycleOwner owner);

    void onPause(LifecycleOwner owner);

    void onStop(LifecycleOwner owner);

    void onDestroy(LifecycleOwner owner);
}
Copy the code

Annotations are a good way to solve these problems. However, annotations either rely on reflection, which can degrade runtime performance; Or rely on APT to slow down compilation.

Starting with Java8, you can add a default method to an interface that the interface implementation class can inherit without having to override. Java8 is now almost the default configuration of the Android project, and you can add the default method to the interface directly instead of using annotations.

For example, the officially recommended DefaultLifecycleObserver

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