Jetpack Lifecycle source code analysis

Keywords: Android Android Studio kotlin

1, Lifecycle

Lifecycle is a lifecycle aware component in Jetpack. It is used to store information about the lifecycle state of an Activity or Fragment, and allow other objects to observe this state.

Lifecycle uses state and event enumerations to track the lifecycle state of its associated components.

2, Basic use  

Using Lifecycle to observe the changes in the entire Activity Lifecycle, you only need to associate Lifecycle with the observer through the addObserver method of the Lifecycle class. Whenever the Lifecycle method of an Activity is called, the corresponding method with the same name of the defaultlifecycle observer interface will also be triggered.

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // The observer is associated with the observed
        lifecycle.addObserver(MyObserver())
    }
    
    class MyObserver : DefaultLifecycleObserver {
        override fun onResume(owner: LifecycleOwner) {

        }

        override fun onPause(owner: LifecycleOwner) {

        }
    }

}

Because the lifecycle owner interface is implemented in the parent class of AppCompatActivity in version 26.1.0 and later, the above code can directly obtain the lifecycle. If a custom class wants to implement the lifecycle owner interface by itself, you can use the lifecycle registry class.

class MainActivity : Activity(), LifecycleOwner {

    private lateinit var lifecycleRegistry: LifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleRegistry = LifecycleRegistry(this)
        lifecycleRegistry.currentState = Lifecycle.State.CREATED
    }

    public override fun onStart() {
        super.onStart()
        lifecycleRegistry.currentState = Lifecycle.State.STARTED
    }

    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }

}

3, Source code

Lifecycle class

Lifecycle is an abstract class, and the implementation class is lifecycle registry, which contains three abstract methods, events and states

Even class: Lifecycle events dispatched by Lifecycle class, which map to callback events in Activity and Fragment. For example, the onCreate method of an Activity is mapped to ON_CREATE event.

State class: the current Lifecycle state of the component tracked by Lifecycle.

public abstract class Lifecycle {

    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    AtomicReference<Object> mInternalScopeRef = new AtomicReference<>();

    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);

    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);

    @MainThread
    public abstract State getCurrentState();

    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;
        }
    }
}

ReportFragment class

ReportFragment is a Fragment without UI, which is added in the onCreate method of ComponentActivity inherited by AppCompatActivity. The life cycle of ReportFragment exactly corresponds to the life cycle of the bound Activity. Each life cycle method in the following code will execute the dispatch method to pass the corresponding events, that is, handle the life cycle events of Activity.

The dispatch method of ReportFragment will judge whether the Activity implements the LifecycleOwner interface or LifecycleRegistryOwner (which has been discarded). Finally, it will call the handlelifcycleevent method of LifecycleRegister and pass the Event to the LifecycleRegistry class.

    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 instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }
    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }

    @Override
    public void onResume() {
        super.onResume();
        dispatchResume(mProcessListener);
        dispatch(Lifecycle.Event.ON_RESUME);
    }

    @Override
    public void onPause() {
        super.onPause();
        dispatch(Lifecycle.Event.ON_PAUSE);
    }

    @Override
    public void onStop() {
        super.onStop();
        dispatch(Lifecycle.Event.ON_STOP);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
        // just want to be sure that we won't leak reference to an activity
        mProcessListener = null;
    }

LifecycleRegistry class

The LifecycleRegistry class is the implementation class of Lifecycle, which implements specific event callback and state management. After receiving the observer (LifecycleObserver) by the addObserver method, it is passed to the Lifecycle through the observer withstate, packaged as the LifecycleEventObserver object, and finally distributed uniformly through LifecycleEventObserver.onStateChanged, All information of LifecycleObserver is obtained through reflection.

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        ...
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
            popParentState();
            // mState / subling may have been changed recalculate
            targetState = calculateTargetState(observer);
        }
        ...
    }
    static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        ObserverWithState(LifecycleObserver observer, State initialState) {
            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;
        }
    }

On the other hand, after receiving the Event of ReportFragment, LifecycleRegistry will convert it to the corresponding State according to the Event, and then update the local mState. If the State is different, it will execute the sync method to synchronize the life cycle of the host and Lifecycle.

    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);
    }

    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;
    }

The synchronization of events, state transition and life cycle is shown in the figure below, which is easier to understand with the help of the official figure.

The arrows from left to right are forward events, and the arrows from right to left are backward events. In the sync method, the enumerated values are compared to determine whether to execute forward or backward, that is, the forwardPass method and the backwardPass method.

Assume that the mState of the current Lifecycle is in the status, and the event passed from the ReportFragment is ON_RESUME, when the event advances, the mState changes to RESUMED; When the event passed by ReportFragment is ON_STOP, when the event reverses, the mState changes to CREATED.

After the local mState state is updated, the ObserverWithState.dispatchEvent method will be called for event notification.

    private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        ...
        while (!isSynced()) {
            mNewEventOccurred = false;
            // no need to check eldest for nullability, because isSynced does it for us.
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                backwardPass(lifecycleOwner);
            }
            Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
            if (!mNewEventOccurred && newest != null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);
            }
        }
    }

4, Summary

1. AppCompatActivity and Fragment in 26.1.0 and later versions implement the lifecycle owner interface, so you can directly obtain getLifecycle;

2. A ReportFragment without UI is bound in the onCreate method of the ComponentActivity class. The life cycle of the ReportFragment is exactly the same as that of the Activity. Internally, it distinguishes the methods of obtaining life cycle events for systems above 29 or below;

3. LifecycleRegistry will package the LifecycleObserver object passed in from the external addObserver into a LifecycleEventObserver object, and complete the event callback by calling the onStateChanged method of LifecycleEventObserver.

Posted by ibelimb on Wed, 17 Nov 2021 05:25:09 -0800