LifeCycle is what LifeCycle does: A LifeCycle aware component can perform operations in response to changes in the LifeCycle state of another component, such as an Activity or Fragment. These components help you write more organized and often leaner code that is easier to maintain (as explained on the Android website). Lifecycle was first introduced in Support 26.1.0 and is now part of the source code with little additional need for users to configure dependencies in Gradle. Lifecycle can help us perceive the Lifecycle.

The use of LifeCycle will not be repeated here by looking directly at the official documentation, but this article aims to understand the nature of LifeCycle and the design of good code.

Background reasons for Lifecycle’s appearance

Before LifeCycle occurs, if an external class listens for the LifeCycle of an Activity/Fragment, it needs to define an interface to listen for Activity LifeCycle methods (onCreate onStart onResume, etc.). Avoid memory leaks and other problems. As the Activity becomes more and more complex, the Listener processes more and more things, which makes the code difficult to maintain.

class MyLocationListener {
    public MyLocationListener(Context context, Callback callback) {
        // ...
    }

    void start() {
        // connect to system location service
    }

    void stop() {
        // disconnect from system location service}}class MyActivity extends AppCompatActivity {
    private MyLocationListener myLocationListener;

    @Override
    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, (location) -> {
            // update UI
        });
    }

    @Override
    public void onStart() {
        super.onStart();
        myLocationListener.start();
        // manage other components that need to respond
        // to the activity lifecycle
    }

    @Override
    public void onStop() {
        super.onStop();
        myLocationListener.stop();
        // manage other components that need to respond
        // to the activity lifecycle}}Copy the code

So how does Lifecycle implement component isolation?

Lifecycle implements isolation

There are two key interfaces that you can see in the official Android documentationLifecycleOwner Indicates that the class has LifecycleLifecycleObserver** Listens for life cycle events ** as well [LifecycleRegistry](https://developer.android.com/reference/androidx/lifecycle/LifecycleRegistry?hl=zh-cn)** Forward Lifecycle events ** Now we implement the full flow of Lifecycle by defining the LifecycleOwner.

open class LActivity:Activity(),LifecycleOwner {

    /** * is responsible for forwarding life cycle events */
    private var mFragmentLifecycleRegistry = LifecycleRegistry(this)

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
    }

    override fun onStart(a) {
        super.onStart()
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
    }

    override fun onResume(a) {
        super.onResume()
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
    }

    override fun onStop(a) {
        super.onStop()
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
    }

    override fun onDestroy(a) {
        super.onDestroy()
        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    }

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

LifecycleEventObserver listens for the lifecycle:

class LifecycleActivity : LActivity() {
    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_lifecycle)
        // Perceive the lifecycle
        lifecycle.addObserver(MyLifecycleObserver())
    }
}

/** * listen to the lifecycle */
class MyLifecycleObserver:LifecycleEventObserver{
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        Log.e("MyLifecycleObserver"."onStateChanged: ${source.lifecycle.currentState} event:${event}")}}Copy the code

The results are as follows: Lifecycle events and the corresponding statesThe official Android documentation gives the relationship between events and states, as shown in the figure below, which is consistent with what we have described above. Events are the ones that listen to the lifecycle and states are the ones that determine whether a page is active.

ON_CREATE and ON_STOP correspond to CREATED. ON_START and ON_PAUSE correspond to STARTED. This is because ON_PAUSE has the potential to restart onStart and ON_STOP has the potential to restart onCreate

So why should Lifecycle design events and states?

Lifecycle events and state

  • Event: ImplementedLifecycleObserverThird party components that can be used inonCreateonDestroyThe life cycle monitoring is completed in the event method. Event is for the internal observer of the third-party component to observe the page push to the component.
  • The state: Lifecycle safety notification (in the previous article how LiveData can safely observe data, the core code of LiveData was explained about Lifecycle). State is for the page as an observer. To look at the push to the page from third party components and by state we can ensure that no push from LifeCycle based components such as LiveData will be received while the page is inactive.

LiveData determines whether the life cycle is active based on State, as follows:

lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
Copy the code

Only onResume and onPause are in between STARTED and RESUMED, That is, only these two lifecycle nodes are 100% sure to receive LiveData’s push (FragmentActivity additionally supports receiving during onStart). (The role of state is described in the Relearn Android column.)

LifecycleRegistry core classes

LifecycleRegistry designs how to distribute events. In fact, see the source code can be similar to LiveData distribution messages.

The following code: Sends a lifecycle event via handleLifecycleEvent

   // Distribute lifecycle events
   public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        enforceMainThreadIfNeeded("handleLifecycleEvent");
        moveToState(event.getTargetState());
    }

    privatevoid moveToState(State next) { ...... sync(); . }private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get(a); .while(! isSynced()) { mNewEventOccurred =false;
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                backwardPass(lifecycleOwner);
            }
            Map.Entry<LifecycleObserver, ObserverWithState> newest =
                mObserverMap.newest();
            if(! mNewEventOccurred && newest ! =null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);
            }
        }
        mNewEventOccurred = false;
    }
Copy the code

The sync() method calls forwardPass and backwardPass, respectively, to distribute life cycle events. Listen for life cycle events and state: the mObserverMap store listens for ObserverWithState

    private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
            new FastSafeIterableMap<>();
Copy the code

AddObserver adds listener events and wraps obSever as ObserverWithState(this code is similar to observer in LiveData)

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        enforceMainThreadIfNeeded("addObserver");
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        / / the observer ObserverWithState packing
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        / / mObserverMap storage statefulObserver
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

        / /...boolean isReentrance = mAddingObserverCounter ! =0 || mHandlingEvent;
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        // Repeating addObserver returns to the previous state
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            final Event event = Event.upFrom(statefulObserver.mState);
            if (event == null) {
                throw new IllegalStateException("no event up from " + statefulObserver.mState);
            }
            // Send life cycle events
            statefulObserver.dispatchEvent(lifecycleOwner, event);
            popParentState();
            // mState / subling may have been changed recalculate
            targetState = calculateTargetState(observer);
        }

        if(! isReentrance) {// we do sync only on the top level.
            sync();
        }
        mAddingObserverCounter--;
    }
Copy the code

ObserverWithState wrapper classes through the dispatchEvent, through mLifecycleObserver onStateChanged distribute events

    static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        ObserverWithState(LifecycleObserver observer, State initialState) {
            mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
            mState = initialState;
        }

        void dispatchEvent(LifecycleOwner owner, Event event) {
            // Get the status of the event
            State newState = event.getTargetState();
            // Determine the current state
            mState = min(mState, newState);
            // Send events and statusmLifecycleObserver.onStateChanged(owner, event); mState = newState; }}Copy the code