Offer to come, dig friends take it! I am participating in the 2022 Spring Recruit Punch card activity. Click here for details.

Introduction to the

Life-cycle-aware components perform operations in response to changes in the life-cycle 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.

The important classes associated with Lifecycle are listed above and will be described below.

  1. LifecycleIs the abstract class, the meaning of existence is to sense the life cycle, distributed to the observer;
  2. LifecycleObserverIs an interface for observing life cycle changes;
  3. LifecycleRegistryisLifecycleConcrete implementation classes, concrete operations are implemented inside it.

Lifecycle class

Lifecycle is an abstract class that contains two important enumerated classes, State and Event.

State indicates the status of the current life cycle. Event indicates the events of the current life cycle.

State: DESTROYED, CREATED, STARTED, RESUMED, and INITIALIZED;

Events consist of onCreate, OnStart, OnResume, OnPause, OnStop and OnDestroy. It can be found that the life cycles of events and activities are basically the same, so that we can understand the concept of Event well.

Based on the above figure, we can clearly understand the relationship between Event and State.

Lifecycle also has two important methods in the Lifecycle class, addObserver(LifecycleObserver Observer) and Remove (LifecycleObserver Observer). Observer is an observer, Used to sense changes in the current life cycle.

LifecycleObserver

LifecycleObserver is an interface that doesn’t provide any methods, but Google provides us with two convenient interfaces.

public interface LifecycleObserver {

}
Copy the code

Just look at the empty interface, we are very confused, how there is an interface definition, there is no method, but we look at the following two interfaces will be suddenly clear.

public interface DefaultLifecycleObserver extends FullLifecycleObserver { @Override default void onCreate(@NonNull LifecycleOwner owner) { } @Override default void onStart(@NonNull LifecycleOwner owner) { } @Override default void onResume(@NonNull LifecycleOwner owner) { } @Override default void onPause(@NonNull LifecycleOwner owner) { } @Override default void onStop(@NonNull LifecycleOwner owner) { } @Override default void onDestroy(@NonNull LifecycleOwner owner) { }}Copy the code

DefaultLifecycleObserver inherits FullLifecycleObserver, which also provides six default methods. Seeing the names of these methods makes it clear what they do, almost exactly like the Activity lifecycle. Yes, It is the callback method of these lifecycle, and we can add our own logic to the corresponding lifecycle callback.

public interface LifecycleEventObserver extends LifecycleObserver {
    /**
     * Called when a state transition event happens.
     *
     * @param source The source of the event
     * @param event The event
     */
    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
Copy the code

LifecycleEventObserver is, as its name suggests, an observation of the lifecycle time, which is called back to onStateChanged() if an event changes, and we can add different logic depending on the event.

The two default interfaces provided by Google give us a deeper understanding of the LifecycleObserver.

LifecycleRegistry

LifecycleRegistry is an implementation class for Lifecycle and, as we can see in the mind map, it maintains two important variables internally: Lifecycle

  • observerMapIs aMapObject for savingLifecycleObserverA set of;
  • LifecycleOwnerAn object that records an observed, usuallyActivityorFragment.

Let’s focus on the source code to see how LifecycleRegistry manages the Observer and distributes events.

public class LifecycleRegistry extends Lifecycle { /** * Custom list that keeps observers and can handle removals / additions during traversal. * * Invariant: at any moment of time for observer1 & observer2: * if addition_order(observer1) < addition_order(observer2), then * state(observer1) >= state(observer2), */ private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>(); private final WeakReference<LifecycleOwner> mLifecycleOwner; /** * Set current State, Observers * * @param state new * * Moves the Lifecycle to the given state and dispatches necessary events to the observers. * * @param state new state */ @MainThread public void setCurrentState(@NonNull State state) { enforceMainThreadIfNeeded("setCurrentState"); moveToState(state); } /** * handle life cycle events, convert to State according to the corresponding Event, Observers * Sets the current state and notifies the observers. * <p> * Note that if the {@code currentState} is the same state as the last call to this method, * calling this method has no effect. * * @param event The event that was received */ public void handleLifecycleEvent(@NonNull Lifecycle.Event event) { enforceMainThreadIfNeeded("handleLifecycleEvent"); moveToState(event.getTargetState()); } 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; } @Override public void addObserver(@NonNull LifecycleObserver observer) { enforceMainThreadIfNeeded("addObserver"); State initialState = mState == DESTROYED? DESTROYED : INITIALIZED; ObserverWithState statefulObserver = new ObserverWithState(Observer, initialState); // Put statefulObserver into observerMap, ObserverWithState Previous = mobServerMap. putIfAbsent(Observer, statefulObserver); if (previous ! = null) { return; } LifecycleOwner lifecycleOwner = mLifecycleOwner.get(); if (lifecycleOwner == null) { // it is null we should be destroyed. Fallback quickly return; } boolean isReentrance = mAddingObserverCounter ! = 0 || mHandlingEvent; State targetState = calculateTargetState(observer); mAddingObserverCounter++; 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); } 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--; } /** * to synchronize events and states */ private void sync() {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. 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

AddObserver (Observer) This method is to add an observer to the Map, adding the same object only once;

HandleLifecycleEvent (Event) is used to process Lifecycle.Event is completed by synchronizing all observer states in the current Map with the current mState.

The early experience of Lifecycle

To make Lifecycle easier to use, the DefaultLifecycleObserver class has been wrapped around Lifecycle to be aware of the full declaration cycle. Let’s try this with a simple example.

class ObserverActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState) setContentView(r.layout.activity_observer) // Add an observer lifecycle.addObserver(MyLifecycleObserver()) } } class MyLifecycleObserver : DefaultLifecycleObserver { private val TAG = "MyLifecycleObserver" override fun onCreate(owner: LifecycleOwner) { super.onCreate(owner) Log.d(TAG, "onCreate: ") } override fun onStart(owner: LifecycleOwner) { super.onStart(owner) Log.d(TAG, "onStart: ") } override fun onResume(owner: LifecycleOwner) { super.onResume(owner) Log.d(TAG, "onResume: ") } override fun onPause(owner: LifecycleOwner) { super.onPause(owner) Log.d(TAG, "onPause: ") } override fun onStop(owner: LifecycleOwner) { super.onStop(owner) Log.d(TAG, "onStop: ") } override fun onDestroy(owner: LifecycleOwner) { super.onDestroy(owner) Log.d(TAG, "onDestroy: ") } }Copy the code

Now that we want to listen for an Activity’s declaration cycle, instead of writing a bunch of listener callbacks, we just inherit DefaultLifecycleObserver and add that object to the Activity’s Lifecycle object. We then overwrite the lifecycle we want to listen to in the Observer.

Lifecycle how does Lifecycle listen for an Activity declaration cycle

The key steps for this section need to be found in ComponentActivity and ReportFragment. Let’s look at the entry:

public class ComponentActivity extends androidx.core.app.ComponentActivity implements ContextAware, LifecycleOwner... { private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { // Restore the Saved State first so that it is available to // OnContextAvailableListener instances mSavedStateRegistryController.performRestore(savedInstanceState); mContextAwareHelper.dispatchOnContextAvailable(this); super.onCreate(savedInstanceState); / / bind a blank fragments, to sense the Activity, so that ensure the Activity code is not redundant ReportFragment. InjectIfNeededIn (this); if (mContentLayoutId ! = 0) { setContentView(mContentLayoutId); }}}Copy the code

At this point, the Activity is bound to both LifecycleRegistry and ReportFragment, so there’s nothing left to do with the Activity. All the answers we need are in the magic ReportFragment.

public class ReportFragment extends android.app.Fragment { @SuppressWarnings("deprecation") 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(); Lifecycle instanceof LifecycleRegistry (lifecycle instanceof LifecycleRegistry) {lifecycle instanceof LifecycleRegistry (lifecycle instanceof LifecycleRegistry) lifecycle).handleLifecycleEvent(event); } } } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); dispatchCreate(mProcessListener); // Dispatch events (Lifecycle. Event.on_create); }... @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; } 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.injectIfNeededIn dispatch(getActivity(), event); }}}Copy the code

LifecycleRegistry allocates different events in the Fragment lifecycle, and then hands them over to LifecycleRegistry to handle these events.

The document

The official documentation

Lifecycle version