1. The Lifecycle

  • Lifecycle is a Lifecycle aware component that performs actions 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.
  • In our previous development, there were a lot of memory problems indirectly caused by the Lifecycle of activities or fragments, such as writing resources every time, or collecting and releasing control tools. If you forget to write resources, you may cause memory leaks. Now with Lifecycle, we can call back the Lifecycle. Instead of adding logical code to a lifecycle as before, write the corresponding code in advance to better solve the lifecycle problem.

2. Life cycle acquisition comparison

2.1 Prior to lifecycle acquisition

  • We need the Activity to override each lifecycle method, adding logic to it so that if a collection is forgotten, it can trigger a memory leak.
override fun onPause(a) {
    super.onPause()
    Log.d(TAG, "onPause")}override fun onStop(a) {
    super.onStop()
    Log.d(TAG, "onStop")}override fun onStart(a) {
    super.onStart()
    Log.d(TAG, "onStart")}override fun onResume(a) {
    super.onResume()
    Log.d(TAG, "onResume")}override fun onRestart(a) {
    super.onRestart()
    Log.d(TAG, "onRestart")}override fun onDestroy(a) {
    super.onDestroy()   
    Log.d(TAG, "onDestroy")}Copy the code

2.2 Lifecycle indicates the callback Lifecycle

  • Lifecycle is very convenient. If you write a custom View or tool that needs Lifecycle awareness, you can use Lifecycle to write logic internally and code more indirectly. The user should also not be aware of creating a collection problem.
lifecycle.addObserver(object : LifecycleEventObserver {
    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
      Log.d(TAG,event.toString())
    }
})
Copy the code

3. Source code analysis

3.1 Class diagram

  • Lifecycle is obtained in the Activity, which is actually obtained by the Activity’s parent ComponentActvitiy, which implements the LifecycleOwner interface, Lifecycle will be available, and finally LifecycleObserver will be available for Lifecycle callbacks.

3.2 ComponentActvitiy. OnCreate

  • You can see the ReportFragment creation in the onCreate method for ComponentActvitiy.
	/* ComponentActvitiy */
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {... ReportFragment.injectIfNeededIn(this); . }Copy the code

3.3 getLifecycle method

	/* ComponentActvitiy */
  	private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
  	
    @NonNull
    @Override
    public Lifecycle getLifecycle(a) {
        return mLifecycleRegistry;
    }
Copy the code

3.4 Lifecycle. The Event

  • Lifecycle.Event is an enumerated class where Lifecycle events are not fragments and will be used later in Lifecycle processing.
    public enum Event { ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY, ON_ANY; . }Copy the code

3.5 Creating ReportFragment

  • The ReportFragment is a type of Fragment that has no interface. It is a type of Fragment that can sense the life cycle by using invisible fragments, so that users do not have to worry about the life cycle.
  • Above SDK29 version using LifecycleCallbacks. RegisterIn (activity).
	/* ReportFragment */
    public static void injectIfNeededIn(Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            // On API 29+, we can register for the correct Lifecycle callbacks directly
            LifecycleCallbacks.registerIn(activity);
        }
        // Prior to API 29 and to maintain compatibility with older versions of
        // ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
        // need to support activities that don't extend from FragmentActivity from support lib),
        // use a framework fragment to get the correct timing of Lifecycle events
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            // Hopefully, we are the first to make a transaction.manager.executePendingTransactions(); }}Copy the code

3.6 LifecycleCallbacks. RegisterIn (activity)

  • LifecycleCallbacks implemented Application. ActivityLifecycleCallbacks interface, above SDK29 distribution is distributed by the Application of life cycle, the activity can callback registration.
  • Well-known LeakCanary in monitoring the Activity life cycle, and using Application. ActivityLifecycleCallbacks.
    @RequiresApi(29)
    static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
    
        static void registerIn(Activity activity) {
            activity.registerActivityLifecycleCallbacks(newLifecycleCallbacks()); }...@Override
        public void onActivityPostCreated(@NonNull Activity activity,
                @Nullable Bundle savedInstanceState) { dispatch(activity, Lifecycle.Event.ON_CREATE); }... }Copy the code

3.7 ReportFragment.dispatch Version Compatible

  • If the SDK version is less than 29, the Dispatch method will be called in each lifecycle ReportFragment method.
  • Such as onActivityCreated.
  • Anyway, whether using LifecycleCallbacks. RegisterIn (activity), or a Fragment of life cycle correction, finally will dispatch.
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(Lifecycle.Event.ON_CREATE);
    }

    private void dispatch(@NonNull Lifecycle.Event event) {
        if (Build.VERSION.SDK_INT < 29) {
            // Only dispatch events from ReportFragment on API levels prior
            // to API 29. On API 29+, this is handled by the ActivityLifecycleCallbacks
            // added in ReportFragment.injectIfNeededIndispatch(getActivity(), event); }}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

3.8 Lifecycle. The State

  • The relationship of this class to Lifecycle.Event can be understood by looking at the diagram.
  • There are only five states but there are more than five life cycles, so when They design, Google creates the process and destroys the process.

	/* Lifecycle.State */
    public enum State {
        DESTROYED,
      
        INITIALIZED,
      
        CREATED,
     
        STARTED,

        RESUMED;
        
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0; }}Copy the code

3.9 handleLifecycleEvent

  • LifecycleRegistryOwner also inherits LifecycleOwner, so they all end up executing the handleLifecycleEvent method of LifecycleRegistry.
  • Lifecycle.Event is processed and converted to Lifecycle.State.
	/* Lifecycle.Event */
        @NonNull
        public State getTargetState(a) {
            switch (this) {
                case ON_CREATE:
                case ON_STOP:
                    return State.CREATED;
                case ON_START:
                case ON_PAUSE:
                    return State.STARTED;
                case ON_RESUME:
                    return State.RESUMED;
                case ON_DESTROY:
                    return State.DESTROYED;
                case ON_ANY:
                    break;
            }
            throw new IllegalArgumentException(this + " has no target state");
        }
Copy the code
  • Lifecycle.State is passed down and saved in mState and then processed in sync.

	/* LifecycleRegistry */
    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        enforceMainThreadIfNeeded("handleLifecycleEvent");
        moveToState(event.getTargetState());
    }

    private void moveToState(State next) {
        if (mState == next) {
            return;
        }
        // Save the state
        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

3.10 the sync

  • The mState saved by the previous method is used for comparison to determine whether the life cycle is being executed forward or backward.
	/* LifecycleRegistry */
    private void sync(a) {
    	// This is a weakly referenced wrapped LifecycleOwner
        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.");
        }
        while(! isSynced()) { mNewEventOccurred =false;
            // no need to check eldest for nullability, because isSynced does it for us.
            // Compare the mState saved by the previous method with the mState saved by the previous component
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            	// Go back to the execution process
                backwardPass(lifecycleOwner);
            }
           
            Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
            if(! mNewEventOccurred && newest ! =null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                // Forward execution process
                forwardPass(lifecycleOwner);
            }
        }
        mNewEventOccurred = false;
    }
Copy the code

3.11 forwardPass

  • The reverse logic is similar, except that backwardPass is executed, Stata is converted, and observer.dispatchEvent is executed.
  • Lifecycle.State is passed back to Lifecycle.Event and distributed to the observer.
		/* Lifecycle.Event */
        @Nullable
        public static Event upFrom(@NonNull State state) {
            switch (state) {
                case INITIALIZED:
                    return ON_CREATE;
                case CREATED:
                    return ON_START;
                case STARTED:
                    return ON_RESUME;
                default:
                    return null; }}Copy the code
  • Convert event. upFrom and send observer.dispatchEvent.
	/* LifecycleRegistry */
    private void forwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
                mObserverMap.iteratorWithAdditions();
        while(ascendingIterator.hasNext() && ! mNewEventOccurred) { Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next(); ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                pushParentState(observer.mState);

				/ / conversion
                final Event event = Event.upFrom(observer.mState);
                if (event == null) {
                    throw new IllegalStateException("no event up from " + observer.mState);
                }
				/ / sendobserver.dispatchEvent(lifecycleOwner, event); popParentState(); }}}Copy the code

3.12 Sending the life cycle Status

  • Lifecycle.Event is sent out by ObserverWithState and that’s done and is received by registered subscribers.
    static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

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

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

3.13 Simple flow chart