The content of this article is as follows:

  1. Lifecycle
  2. How do I add a LifecycleObserver
  3. How does Lifecycle implement the callback

Lifecycle

Lifecycle, the cornerstone of the Jetpack component and MVVM, is a very simple fundamental application of the Observer pattern and is very simple to use

  1. Import the Jetpack component implementation ‘androidx. Appcompat: appcompat: 1.2.0’

  2. Define a public class MyLifecycleObserver implements LifecycleObserver, LifecycleObserver is just an empty interface, behind the detail, then The next step is to annotate the methods that need lifecycle call-back. ** This can be interpreted as having the State interface in LifecycleObserver, and then calling your methods in the corresponding interface. ** may be a little harder to understand, but it basically means something like this

    public class MyLifecycleObserver implements LifecycleObserver {
        public static final String TAG = "MyLifecycleObserver";
        // Annotations can be interpreted as the following method
        //@Override
        //public void ON_CREATE() {
        // create();
        / /}
        @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
        public void create(a) {
            Log.d(TAG, "create: ");
        }
        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        public void start(a) {
            Log.d(TAG, "start: ");
        }
        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
        public void resume(a) {
            Log.d(TAG, "resume: ");
        }
        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        public void destroy(a) {
            Log.d(TAG, "destroy: "); }}Copy the code
  3. The callback is then registered where it is needed. An interesting phenomenon here is that when methods are registered in onResume, both create() and start() in MyLifecycleObserver are called, for reasons we’ll talk about later

    @Override
    protected void onResume(a) {
        super.onResume();
        getLifecycle().addObserver(new MyLifecycleObserver());
    }
    Copy the code

Lifecycle class diagram

This may seem complicated, but let’s take a look at the core classes

  1. Lifecycle is an abstract class that will add and remove LifecycleObserver
  2. LifecycleRegistry, a subclass of Lifecycle, implements methods in Lifecycle and triggers call-back in LifecycleObserver
  3. The State,Event, and enumeration types correspond to the State and life cycle of the Activity, respectively.
  4. LifecycleOwner, which is an interface to retrieve Lifecycle, typically returns LifecycleRegistry
  5. ComponentActivity, used to get LifecycleRegistry
  6. ReportFragment, unbounded Fragment, for callbacks to lifecycle methods
  7. ObserverWithState, LifecycleRegistry subclass, through which the callback ReflectiveGenericLifecycleObserver callback methods
  8. ReflectiveGenericLifecycleObserver MyLifecycleObserver decorator classes, through the reflection to call registered its life cycle method

It is important to explain the relationship between State and Event. The INITIALIZED State is a secondary State and is not one of the four states of an Activity. Acitivyt is in four different states: CREATED-> after onCreate(), before onDestroy(), STARTED-> after onStart(), before onStop(), after onResume(), The getStateAfter() method should be named getStateAfterEvent(), which means the State after a lifecycle method is called. More on that later

Lifecycle adds and removes

Removing the observer is very simple, just remove the Observer from the mObserMap and add it from getLifecycle().addobServer (new MyLifecycleObserver()); Began to read, because ComponentActivity LifecycleOwner is achieved, and returns the LifecycleRegistry, so from LifecycleRegistry. AddObserver start ()

Sequence diagram

Explain:

Actor refers to the lifecycle method in an Activity

Loop means loop

Alt indicates that the judgment condition is true

LifecycleRegistry.addObserver()

  1. DESTROY is the smallest, RESUME is the largest, and the initial State is DESTROYED or INITIALIZED (0,1,2,3,4)
  2. Create an ObserverWithState object and push it into FastSafeIterableMap. Note that LifecycleObser is the key. FastSafeIterableMap is not a standard HashMap. Instead of a Map with a two-way list, why not just use LinkedHashMap? Don’t understand,
  3. Determine if the observer exists before, if it already exists, do not add it, for example, in the onResume case, then the user returns to the desktop and re-enters
  4. Determine whether events are being added or processed. Why are they being designed this way
  5. Call calculateTargetState() to calculate State, where the minimum value of mParentStates, mState and Previous State is taken as targetState, for reasons explained later
  6. From the INITIALIZED or DESTROYED state to the target state in turn calls ObserverWithState. The dispatchEvent (), into the distributed event here
  7. If this is the first addition and there is no state change, sync() is called to synchronize all states

ObserverWithState.dispatchEvent()

This part of the logic is simple

  1. Called in the constructorLifecycling.lifecycleEventObserver(observer)Get the current LifecycleEventObserver wrapper classes, annotations, for example, should be returned to ReflectiveGenericLifecycleObserver, LifecycleEventObserver and FullLifecycleObserver. The first one is a user-defined implementation of LifecycleEventObserver, and the second one is a callback method for each Event. Synchronize with the Activity lifecycle
  2. Called after LifecycleEventObserver. OnStateChanged () callback, through reflection after registered in LifecycleObserver annotations, and call the corresponding method

LifecycleRegistry.sync()

  1. IsSynced () is called to determine whether all observers have been updated to the latest State. The value of isSynced() is used to determine the head and tail of the bidirectional list. This leads to a very important concept, that is, all observers are ordered according to the time of joining, and the observer added first is called first
  2. First of all to seemState.compareTo(mObserverMap.eldest().getValue().mState) < 0This condition, that is, the head node in the bidirectional list is greater than the current State, which obviously occurs in the onResume->onPause->onStop lifecycle calls, so revert to the current mState for each head node and call the corresponding method in the Observer
  3. Then,! mNewEventOccurred && newest ! = null && mState.compareTo(newest.getValue().mState) > 0MNewEventOccurred is not very understandable, unless it is multi-threaded, it should not appear this kind of judgment, newest is easier to understand, when the process of distributing events, it is possible that all the observers will remove themselves may appear this situation, finallymState.compareTo(newest.getValue().mState)>0, obviously in the onCreate->onStart->onResume lifecycle
  4. BackwardPass is similar to forwardPass. ForwardPass traverses from front to back, ensuring that ON_CREATE->ON_START->ON_RESUME is called in ascending order. BackwardPass, on the other hand, traverses from back to front. Make sure that ON_PAUSE->ON_STOP traverses back to front

What is observer orderliness

Lifecycle will be called from onCreate->onStart->onResume before the later observer and onPause->onStop after the later observer

The role of isReentrance

Consider a scenario where a new observer is added to an onStart() method of an observer, which I call subscription nesting. In this case, to ensure the effect of synchronization only once, So it is set to synchronize only when the first Observer is added and mHandlingEvent is false, since mHandlingEvent true will synchronize itself

CalculateTargetState () Calculation method

If the subscription is set to mState, the onResume() method of the observer will precede the onResume() method of the observer.

The role of mParentStates

Here are some official examples:

void onStart(a) {
    mRegistry.removeObserver(this);
    mRegistry.add(newObserver);
    //may have others logic
}
Copy the code

How to understand this example:

  1. OnStart () is a method in a lifecycleObserver, not an Activity,
  2. Let’s make an assumption here: If mParentStates is RESUMED, null is RESUMED because mState is RESUMED, and previous is deleted. If mParentStates is RESUMED, null is RESUMED because previous is RESUMED. The new observer will be called from ON_CREATE->ON_START->ON_RESUME, but the onStart() of the removed observer may not have run out of logic, which may not meet the application requirements. It should be after onStart runs and then the new observer starts calling. MParentStates is now involved. Since mParentStates stores the STARTED state of the current Observer, the Observer targetState is set to CREATED, rather than directly to RESUMED

How does Lifecycle implement the callback

Lifecycle’s callback can be done in two ways:

  1. AddObserver () dispatchEvent()
  2. The life cycle changes or setCurrentState() is called

Sequence diagram

It’s pretty simple from a sequence diagram, but this is just happy Path, and to understand that, you have to dig into how they get annotations through reflection, and then call methods through reflection, which is a little bit more logic but not complicated, right

getStateAfter()

GetStateAfterEvent () = getStateAfterEvent() = getStateAfterEvent(

  1. Each Event variable corresponds to the Activity’s lifecycle method, so I’ll refer to it as the lifecycle method next
  2. The change in State can be thought of as a linked list of states. It makes sense that the State changes to CREATED after onCreate() is called, but CREATED is a State, so the Activity is CREATED during that time after onStop() is called before onCreate() is called
  3. In other states, after onStart() and onPause(), State becomes STARTED. The RESUMED and DESTROYED states are considered to be the end and head of the State chain. An Activity is not CREATED at first. They should be in a DESTROYED state

Points to note when using Lifecycle

  1. It is best not to add an observer to the child thread. Although the @mainThread tag is not added, the data inside the child thread is not protected
  2. Annotated callback methods do not take any arguments other than the fixed format such asmethod(LifecycleOwner owner)ormethod(LifecycleOwner owner, Lifecycle.Event event)