Lifecycle is what?

Official explanation:

Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state.

Lifecycle is a tool (class) that manages the Lifecycle of a component (Activity/Fragment) and can listen for Lifecycle changes in other components (Activity/Fragment). This component is an important part of the Jetpack Architecture Components library, such as LiveData, ViewModel, and so on, and must be relied upon to implement monitoring and handling lifecycle changes.

How will Lifecycle be used?

DefaultLifecycleObserver

The premise

  • The project is compiled using Java 8
  • Add gradle rely on “androidx lifecycle: lifecycle – common – java8: $lifecycle_version”
class LoginActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        // Register lifecycle listeners
        lifecycle.addObserver(ActivityLifecycleObserver())
    }
}

/** * Lifecycle listener class * implements lifecycle logic to make code logic in LoginActivity more concise */
class ActivityLifecycleObserver: DefaultLifecycleObserver{

    override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)
        // The life cycle executes onResume}}Copy the code

Notes:

Is not recommended. Annotation is called by reflection and has a performance cost. class LoginActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.oncreate (savedInstanceState) setContentView(r.layout.activity_login) // Register life cycle listener lifecycle.addObserver(ActivityLifecycleObserver()) } }

/** * Lifecycle listener class * implements lifecycle logic to make code logic in LoginActivity more concise */
class ActivityLifecycleObserver: LifecycleObserver{
    
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume(a){
        // The life cycle executes onResume}}Copy the code

Expand and manage the life cycle autonomously

Very not recommended. This self-maintenance life cycle can lead to race situations.

class LoginActivity : AppCompatActivity() {

    private lateinit var mLifecycleRegistry: LifecycleRegistry

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        
        // Customize LifecycleRegistry here
        mLifecycleRegistry = LifecycleRegistry(this)
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)

        // Register lifecycle listeners
        lifecycle.addObserver(ActivityLifecycleObserver())
    }

    override fun onStart(a) {
        super.onStart()
        // Send LifecycleRegistry via custom LifecycleRegistry, which can override the default implementation
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
    }

    // This method must be overridden to give a custom Registry
    override fun getLifecycle(a): Lifecycle {
        return mLifecycleRegistry
    }
}

class ActivityLifecycleObserver: LifecycleObserver{

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume(a){
        // The life cycle executes onResume}}Copy the code

What is the principle of Lifecycle?

Understand Event and State

Before starting the source code explanation, first understand the relationship between Event and State. This is important because there are often transitions between Event and State in the source code, and you need to rely on their diagrams () to facilitate understanding.

The Event:Lifecycle an enumerated class that sends the corresponding Lifecycle events, including onCreate, onStart, and other Lifecycle events.

The State:Lifecycle is the Lifecycle state of a process that is mapped to events.

Realize the principle of

FragmentActivity # HostCallbacks class: FragmentActivity # HostCallbacks The source code is based on Lifecycle 2.2.0 and Acitivity 1.1.0.

Source code analysis is divided into two parts, starting from the call method, generally know the internal logic, and then start from the question, to answer the doubts in the mind.

Start by calling the method

/ * * * there are three parts: the lifecycle, addObserver (), ActivityLifecycleObserver object * lifecycle: Corresponding getLifecycle () method, to obtain object Lifecycle * addObserver () : call addObserver Lifecycle object () method * ActivityLifecycleObserver objects: This is the class object that implements the DefaultLifecycleObserver interface */
lifecycle.addObserver(ActivityLifecycleObserver())
Copy the code

As you can see by calling the methods, you need to look at the internal logic of the getLifecycle() and addObserver() methods. Internal implementation of getLifecycle() : As you can see from the following code, the getLifecycle() method is actually implemented in ComponentActivity and a LifecycleRegistry object is created that is returned by this method.

public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner{
    / /... Omit...

    // Directly new a LifecycleRegistry object.
    // What does this class do? We'll look at that later.
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    / /... Omit...

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

    / /... Omit...

}
Copy the code

Internal implementation of addObserver() : The code shows that LifecycleRegistry is the actual lifecycle management class, which is why getLifecycle() above returns a LifecycleRegistry object. It looks like a lot of code, but it’s the core part, so to summarize:

  1. The addObserver() method is called, internally given an initial state, bound to an Observer(via ObserverWithState), and the sync() method is called.
  2. The sync() method internally determines whether to go forward (forwardPass()) or back (backwardPass()) based on the difference between the states. (Here we go forward as an example)
  3. ForwardPass () internally calls the upEvent() method to convert observer State to Event, and then calls ObserverWithState#dispatchEvent() for distribution.
  4. At this point, our self-implemented Observer class will receive a lifecycle callback.

PS: note that lifecyclerestring #mState is not confused with ObserverWithState#mState.

public class LifecycleRegistry extends Lifecycle {

    / /... Omit...

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {

        // Given an initial state, create an ObserverWithState object, pass in the state and observer,
        // Then store the ObserverWithState object into the map
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

        / /... Omit...

        if(! isReentrance) {// we do sync only on the top level.
            sync();
        }
            
        / /... Omit...
    }

    / /... Omit...

    private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get(a);/ /... Omit...
    
        // Use the isSynced() method to determine whether the state is aligned.
        // The following logic is used to determine whether to go forward or backward.
        // Use the "State and Event diagram" to understand.
        / / such as:
        ; // Displays a new Activity, mState = Created, mobServermap.eldest ().getValue().mstate = INITIALIZED,
        // newest.getValue().mstate = INITIALIZED. Execute the forwardPass() method (go ahead) using the following logic
        while(! isSynced()) {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); }}}/ /... Omit...

    private void forwardPass(LifecycleOwner lifecycleOwner) {
        Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
                mObserverMap.iteratorWithAdditions();
        while(ascendingIterator.hasNext() && ! mNewEventOccurred) { Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next(); ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                    && mObserverMap.contains(entry.getKey()))) {
                pushParentState(observer.mState);

                Call upEvent() to get the Event corresponding to the current State.
                // The dispatchEvent() method is then called with ObserverWithStateobserver.dispatchEvent(lifecycleOwner, upEvent(observer.mState)); popParentState(); }}}/ /... Omit...

    // State goes to Event. Refer to the "State and Event Diagram" to understand
    private static Event upEvent(State state) {
        switch (state) {
            case INITIALIZED:
            case DESTROYED:
                return ON_CREATE;
            case CREATED:
                return ON_START;
            case STARTED:
                return ON_RESUME;
            case RESUMED:
                throw new IllegalArgumentException();
        }
        throw new IllegalArgumentException("Unexpected state value " + state);
    }

    / /... Omit...


    // Static inner class used to bind observer to State
    static class ObserverWithState {
        State mState;
        LifecycleEventObserver mLifecycleObserver;

        ObserverWithState(LifecycleObserver observer, State initialState) {

            // There is a layer of conversion for the Observer class. Internal annotation of the way to achieve, you can view.
            mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);

            mState = initialState;
        }


        // Pass Event to State to deliver the current Event Event and update observer Statevoid dispatchEvent(LifecycleOwner owner, Event event) { State newState = getStateAfter(event); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; }}/ /... Omit...
}
Copy the code

Start with questions

1. How does Lifecycle listen for the Lifecycle? How are other components notified of life cycle changes? You didn’t see how to listen for lifecycle changes from “call methods” above, so where is this piece of logic? ReportFragment#injectIfNeededIn() is called in the ComponentActivity#onCreate() method. The ReportFragment is the actual lifecycle provider (observed), which internally provides lifecycle changes and delivers them by calling the LifecycleRegistry#handleLifecycleEvent() method. Inside the handleLifecycleEvent() method, pass the Event to State, then call the sync method, and the rest of the logic is the same as in “firing from calling method” (see the internal implementation section of addObserver()).

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

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSavedStateRegistryController.performRestore(savedInstanceState);

        / / here
        ReportFragment.injectIfNeededIn(this);
        if(mContentLayoutId ! =0) { setContentView(mContentLayoutId); }}}// The actual life cycle is observed
public class ReportFragment extends Fragment {
    / /... The lifecycle logic is omitted and dispatch() is called at the end...

    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();

        / /... Omit...

        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {

                    // Invoke the LifecycleRegistry#handleLifecycleEvent() method to trigger the event((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); }}}}public class LifecycleRegistry extends Lifecycle {
    / /... Omit...

    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        // Get State based on the Event passed in
        State next = getStateAfter(event);
        moveToState(next);
    }

    // Update the LifecycleRegistry#mState value and call the sync() method
    private void moveToState(State next) {
        / /... Omit...
        
        mState = next;

        / /... Omit...

        sync();
    }

    / /... Omit...

}
Copy the code

2. If addObserver() is called in onStart(), is it subject to the onCreate life cycle? You can conclude with the following code and comments that you can still get life cycle events if you do not call addObserver() in onCreate().

public class LifecycleRegistry extends Lifecycle {

    / /... Omit...

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {

        / /... Omit...
        
        // The observer State is compared to the current State. If it is later than the current State, dipatchEvent is triggered to catch up with the current life cycle.
        // The point of comparing the two states is that the addObserver() call can still receive the onCreate lifecycle if it is not in onCreate.
        / / such as:
        State = Started, observer State = INITIALIZED,
        // Observer State is later than the current State, dispatchEvent is triggered (INITIALIZED)
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
            popParentState();
            // In case the current State changes while observer State is catching up, call calculateTargetState() to calculate the gap again
            targetState = calculateTargetState(observer);
        }

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

Lifecycle Lifecycle is now inherited from the Activity class. Lifecycle changes are performed at ComponentActivity. If inherited from an Activity, Lifecycle changes can only be maintained by the Activity itself, similar to “expand, manage the Lifecycle”. The difference is that you need to implement the LifecycleOwner interface and maintain the full lifecycle. Here is the sample code:

open class BaseActivity : Activity(), LifecycleOwner{

    private val mLifecycleRegistry = LifecycleRegistry(this)
    
    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
    }
    
    override fun onStart(a) {
        super.onStart()
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
    }
    
    override fun onDestroy(a) {
        super.onDestroy()
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    }
    
    override fun getLifecycle(a): Lifecycle {
        return mLifecycleRegistry
    }
}
Copy the code

conclusion

Lifecycle is implemented with a brief summary: Call ReportFragment at ComponentActivity to listen for lifecycle changes, and call LifecycleRegistry#handleLifecycleEvent() to notify when lifecycle changes occur. The LifecycleRegistry#addObserver() method is then called, which internally converts State to Event and delivers lifecycle events. The following is the call sequence diagram, you can refer to the source code.