What is Lifecycle?
Lifecycle components refer to Android arch. Various classes and interfaces provided under the lifecycle package allow developers to build classes that can sense the lifecycle aware of other components (mainly activities and fragments).
Why introduce Lifecycle?
As I said earlier, Lifecycle enables developers to build classes that can perceive the lifecycle aware of other components (mainly activities and fragments). Focus on building classes that can perceive the lifecycle aware of other components (mainly activities and fragments) (lifecycle aware). In the process of android development, we often need to make some operations aware of the life cycle of Activity/Fragment, so as to allow operations in the active state. In the destruction state, we need to automatically prohibit operations, release resources and prevent memory leakage. For example, the famous picture loading framework Glide is in the foreground of Acticiy/Fragment When the image is loaded, and stop the image loading in the invisible state. For example, we hope that RxJava's dispose can be automatically disposed when the Activity/Fragment is destroyed. With the emergence of lifecycle, developers can easily realize the above functions.
An example of MVP transformed with Lifecycle
For example, we now need to implement such a function: monitor the changes in the life cycle of an Activity and print the log when the life cycle changes.
- General practice: how to construct callbacks
First define the basic IPresent interface:
public interface IPresent { void onCreate(); void onStart(); void onResume(); void onPause(); void onStop(); void onDestory(); }
Then inherit the IPresent interface in the customized Present:
public class MyPresent implements IPresent { private String TAG = "tag"; @Override public void onCreate() { LogUtil.i(TAG, "onCreate"); } @Override public void onStart() { LogUtil.i(TAG, "onStart"); } @Override public void onResume() { LogUtil.i(TAG, "onResume"); } @Override public void onPause() { LogUtil.i(TAG, "onPause"); } @Override public void onStop() { LogUtil.i(TAG, "onStop"); } @Override public void onDestory() { LogUtil.i(TAG, "onDestory"); }
Finally, call the callback method successively in the Activity to distribute events:
public class MyActivity extends AppCompatActivity { protected MyPresent myPresent; @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); myPresent = new MyPresent(); myPresent.onCreate(); } @Override protected void onStart() { super.onStart(); myPresent.onStart(); } @Override protected void onResume() { super.onResume(); myPresent.onResume(); } @Override protected void onPause() { super.onPause(); myPresent.onPause(); } @Override protected void onStop() { super.onStop(); myPresent.onStop(); } @Override protected void onDestroy() { super.onDestroy(); myPresent.onDestory(); } }
Through such a simple example, we can see that although the implementation process is very simple, the code implementation is cumbersome, not flexible enough, and the code is too intrusive. This example only shows the life cycle of Present listening Activity. If there are class 1, class 2, class 3 If you want to listen to the life cycle of an Activity, you need to add class 1, class 2, class 3..... To the callback of the Activity Callback for. This raises a question. Can we realize the function of actively notifying the demander when the life cycle of an Activity changes? Yes, the answer is Lifecycle.
- Lifecycle implementation Present
First implement MyPresent, and add @ onllifecycle event (lifecycle. Event. XXXX) annotation on each method implementation. Onllifecycle event corresponds to the life cycle method of Activity:
public class MyPresent implements IPresent, LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) @Override public void onCreate() { LogUtil.i(TAG, "onCreate"); } @OnLifecycleEvent(Lifecycle.Event.ON_START) @Override public void onStart() { LogUtil.i(TAG, "onStart"); } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) @Override public void onResume() { LogUtil.i(TAG, "onResume"); } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) @Override public void onPause() { LogUtil.i(TAG, "onPause"); } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) @Override public void onStop() { LogUtil.i(TAG, "onStop"); } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) @Override public void onDestory() { LogUtil.i(TAG, "onDestory"); } }
Then register in the Activity to listen:
public class MyActivity extends AppCompatActivity { protected MyPresent myPresent; @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); getLifecycle().addObserver(new MyPresent()); //Add listening object } }
The operation is as follows:
com.cimu.lifecycle I/MyPresent : onCreate() com.cimu.lifecycle I/MyPresent : onStart() com.cimu.lifecycle I/MyPresent : onResume() com.cimu.lifecycle I/MyPresent : onPause() com.cimu.lifecycle I/MyPresent : onStop() com.cimu.lifecycle I/MyPresent : onDestroy()
Is it very simple? We want MyPresent to monitor the life cycle of Activity, only calling getLifecycle () in Activity. Addobserver (New mypresent()) is OK. How does Lifecycle realize the function of perceiving the Lifecycle and then notifying the observer?
Lifecycle source code analysis
First, you need to know three key things:
- Lifecycle owner: the Event distributor of the lifecycle, which sends corresponding events to the lifecycle registry when the lifecycle of the Activity/Fragment changes.
- LifecycleObserver: the observer of the life cycle binds the processing function to the Event that you want to listen to through annotations. When the corresponding Event occurs, LifecycleRegistry will notify the corresponding function to process it.
- Lifecycle registry: control center. It is responsible for controlling the transformation of state, accepting and distributing event events.
The source code analysis of LifeCycle is divided into two steps:
- Registration / logout monitoring process
- *Lifecycle distribution process*
Source code analysis of registration / logout monitoring process
From the MVP example above, we know that registration only needs to call getlifecycle() addObserver (observer), then addObserver can be used as the entry for source code analysis.
Through tracing, we find that getLifecycle returns the mllifecycle registry in SupportActivity. The type is lifecycle registry:
public class SupportActivity extends Activity implements LifecycleOwner { ...... private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>(); private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); ...... @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; } ...... }
addObserver actually calls the addObserver method of lifecycle registry. Let's take a look at this method:
@Override public void addObserver(@NonNull LifecycleObserver observer) { State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; //Encapsulate the incoming listener observer into an observer withstate ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); //Store the encapsulated ObserverWithState into the collection 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); statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState)); popParentState(); // We dispatch an event to the observer. When calling back the observer code, the observer may // Modify our status // mState / subling may have been changed recalculate targetState = calculateTargetState(observer); } if (!isReentrance) { // we do sync only on the top level. sync(); } mAddingObserverCounter--; }
As for the registration process, we focus on the observer withstate encapsulating Observer:
static class ObserverWithState { State mState; GenericLifecycleObserver mLifecycleObserver; ObserverWithState(LifecycleObserver observer, State initialState) { //getCallback() returns different genericlifecycle observer implementation classes through different types of observers mLifecycleObserver = Lifecycling.getCallback(observer); mState = initialState; } //The distribution of life cycle events will eventually call this method. In this method, GenericLifecycleObserver is called //onStateChanged method for void dispatchEvent(LifecycleOwner owner, Event event) { State newState = getStateAfter(event); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; } } public interface GenericLifecycleObserver extends LifecycleObserver { void onStateChanged(LifecycleOwner source, Lifecycle.Event event); }
The constructor of ObserverWithState called lifecycle Getcallback () parses the incoming observer, generates the specific implementation return of the interface class GenericLifecycleObserver, rewrites the onStateChanged method in the specific implementation class, and implements the distribution of the life cycle in onStateChanged. When the life cycle of an Activity/Fragment changes, it will traverse the mbobservermap collection in the lifecycle registry, take out the ObserverWithState node and call its onStateChanged method. In the onStateChanged method of ObserverWithState, it calls the genericlifecycle observer that implements the specific life cycle distribution onStateChanged method.
In analyzing Lifecycle Before using the getcallback () method, let's take a look at the three basic usage methods used by Lifecycle:
- The first way to use. Use @ onllifecycle event annotation. The annotation processor will parse the annotation and dynamically generate the generated adapter code, which will put the corresponding lifecycle Event is encapsulated as a method call. Finally, call the callMechods method of the generated generateadapter through the onStateChanged method of genericlifecycle observer for event distribution (understood in combination with the following example).
public class MyLifeCycleObserver implements LifeCycleObserver { @onLifecycleEvent(LifeCycle.Event.ON_CREATE) public onCreate(LifeCycleOwner owner) { //doSomething } @onLifecycleEvent(LifeCycle.Event.ON_DESTROY) public onDestroy(LifeCycleOwner owner) { //doSomething } } public class MainActivity extends AppCompatActivity { @override public void onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) getLifecycle().addObserver(new MyLifeCycleObserver()); } }
MyLifeCycleObserver in the above example will generate the generatedapter code during compilation, as follows:
public class MyLifeCycleObserver_LifecycleAdapter implements GeneratedAdapter { final MyLifeCycleObserver mReceiver; MyLifeCycleObserver_LifecycleAdapter(MyLifeCycleObserver receiver) { //mReceiver is the MyLifeCycleObserver passed in by our developers this.mReceiver = receiver; } //The callMechod method will be called by the onStateChanged method of genericlifecycle observer to distribute the lifecycle @Override public void callMethods(LifecycleOwner owner, Lifecycle.Event event, boolean onAny, MethodCallsLogger logger) { boolean hasLogger = logger != null; if (onAny) { return; } //If the lifecycle event is ON_CREATE, then call the onCreate method of MyLifeCycleObserver if (event == Lifecycle.Event.ON_CREATE) { if (!hasLogger || logger.approveCall("onCreate", 2)) { mReceiver.onCreate(owner); } return; } //If the lifecycle event is ON_DESTROY, then call the onDestroy method of MyLifeCycleObserver if (event == Lifecycle.Event.ON_DESTROY) { if (!hasLogger || logger.approveCall("onDestroy", 2)) { mReceiver.onDestroy(owner); } return; } } }
- The second way to use. Directly inherit GenericLifecycleObserver and implement onStateChange method
public class MyLifeCycleObserver extends GenericLifeCycleObserver { @override void onStateChanged(LifecycleOwner source, Lifecycle.Event event) { if(event == LifeCycleEvent.Event.ON_CREATE) { //dosomething } else if(event == LifeCycleEvent.Event.ON_DESTROY) { //doSomething } } } public class MainActivity extends AppCompatActivity { @override public void onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) getLifecycle().addObserver(new MyLifeCycleObserver()); } }
- The third way to use. Inherits the DefaultLifecycleObserver interface (DefaultLifecycleObserver inherits from the FullLifecycleObserver interface), and implements the onCreate, onStart, onResume, onPause, onStop, onDestroy and other methods corresponding to their respective lifecycles of the FullLifecycleObserver interface
class MyLifycycleObserver implements DefaultLifecycleObserver { @Override public void onCreate(@NonNull LifecycleOwner owner) { //doSomething } ...... @Override public void onDestroy(@NonNull LifecycleOwner owner) { //doSomething } } public class MainActivity extends AppCompatActivity { @override public void onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) getLifecycle().addObserver(new MyLifeCycleObserver()); } }
We have learned the three basic methods of using Lifecycle. Let's take a brief look at Lifecycle How does the getcallback () method generate the specific implementation class of GenericLifecycleObserver to return:
//First, let's familiarize ourselves with the resolveObserverCallbackType method, which is used in lifecycle getCallback() //Is called in getCallback. According to its return value, getCallback will determine what type of GenericLifecycleObserver implementation class to return private static int resolveObserverCallbackType(Class<?> klass) { if (klass.getCanonicalName() == null) { return REFLECTIVE_CALLBACK; } //When the first method is used for annotation, the code will be generated automatically, and the generated adapter inherits the generated adapter, //So the return value is GENERATED_CALLBACK Constructor<? extends GeneratedAdapter> constructor = generatedConstructor(klass); if (constructor != null) { sClassToAdapters.put(klass, Collections .<Constructor<? extends GeneratedAdapter>>singletonList(constructor)); return GENERATED_CALLBACK; } //The hasLifecycleMethods method is used to determine whether onllifecycle event is included in klass Class annotation //If yes, return responsive_ CALLBACK boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass); if (hasLifecycleMethods) { return REFLECTIVE_CALLBACK; } //Recursively call the resolveObserverCallbackType method to traverse the parent class of klass Class<?> superclass = klass.getSuperclass(); List<Constructor<? extends GeneratedAdapter>> adapterConstructors = null; if (isLifecycleParent(superclass)) { if (getObserverConstructorType(superclass) == REFLECTIVE_CALLBACK) { return REFLECTIVE_CALLBACK; } adapterConstructors = new ArrayList<>(sClassToAdapters.get(superclass)); } //Traverse and recurse the interface of kclass for (Class<?> intrface : klass.getInterfaces()) { if (!isLifecycleParent(intrface)) { continue; } if (getObserverConstructorType(intrface) == REFLECTIVE_CALLBACK) { return REFLECTIVE_CALLBACK; } if (adapterConstructors == null) { adapterConstructors = new ArrayList<>(); } adapterConstructors.addAll(sClassToAdapters.get(intrface)); } if (adapterConstructors != null) { sClassToAdapters.put(klass, adapterConstructors); return GENERATED_CALLBACK; } return REFLECTIVE_CALLBACK; }
//The parameter object of getCallBack is getlifecycle() Addobserver (observer) is the incoming listener static GenericLifecycleObserver getCallback(Object object) { if (object instanceof FullLifecycleObserver) { //The third method is used because DefaultLifecycleObserver inherits from FullLifecycleObserver return new FullLifecycleObserverAdapter((FullLifecycleObserver) object); } if (object instanceof GenericLifecycleObserver) { //In the second way, when we use the method of directly inheriting GenericLifecycleObserver, we directly return return (GenericLifecycleObserver) object; } final Class<?> klass = object.getClass(); //In the first way, when annotations are used, the return value of getObserverConstructorType is GENERATED_CALLBACK int type = getObserverConstructorType(klass); if (type == GENERATED_CALLBACK) { List<Constructor<? extends GeneratedAdapter>> constructors = sClassToAdapters.get(klass); if (constructors.size() == 1) { GeneratedAdapter generatedAdapter = createGeneratedAdapter(constructors.get(0), object); return new SingleGeneratedAdapterObserver(generatedAdapter); } GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()]; for (int i = 0; i < constructors.size(); i++) { adapters[i] = createGeneratedAdapter(constructors.get(i), object); } return new CompositeGeneratedAdaptersObserver(adapters); } //When the Obervers do not conform to the above types, the reflective genericlifecycle observer will be instantiated directly //As an alternative return (generally, it will not come here, which may be a security mode to deal with the confusion mechanism) //In the reflective genericlifecycle observer, you will find the onlife cyleevent annotations in the observer and annotate them //The method of generates a MethodReference and adds it to the list < MethodReference > as the calling method distributed in the life cycle return new ReflectiveGenericLifecycleObserver(object); }
All right, lifecycle If getcallback () really needs to be analyzed in detail, it will be a lot of space. Here, we have a rough analysis. If you want to have an in-depth understanding, it's best to combine your own source code.
Summarize the registration process:
- In Acitivty, the addObserver of LifecycleRegistry is invoked and sent to a LifecycleObserver.
- The incoming lifecycle observer is encapsulated into an ObserverWithState and stored in the collection. When the lifecycle changes, it will traverse the ObserverWithState collection and call the dispatchEvent of ObserverWithState for distribution
- In the ObserverWithState construction method, Lifecycling. is called. Getcallback (observer) generates a specific genericlifecycleobserver object return. In ObserverWithState's dispatchEvent() method, the onStateChanged method of the GenericLifecycleObserver object is invoked for event distribution.
The logoff process is very simple. Directly remove the observer from the collection. The code is as follows:
@Override public void removeObserver(@NonNull LifecycleObserver observer) { // we consciously decided not to send destruction events here in opposition to addObserver. // Our reasons for that: // 1. These events haven't yet happened at all. In contrast to events in addObservers, that // actually occurred but earlier. // 2. There are cases when removeObserver happens as a consequence of some kind of fatal // event. If removeObserver method sends destruction events, then a clean up routine becomes // more cumbersome. More specific example of that is: your LifecycleObserver listens for // a web connection, in the usual routine in OnStop method you report to a server that a // session has just ended and you close the connection. Now let's assume now that you // lost an internet and as a result you removed this observer. If you get destruction // events in removeObserver, you should have a special case in your onStop method that // checks if your web connection died and you shouldn't try to report anything to a server. mObserverMap.remove(observer); }
Lifecycle distribution process
When registering an observer, we actually call the method of the mllifecycle registry object in SupportActivity. Then we analyze the onCreate method of SupportActivity:
@Override @SuppressWarnings("RestrictedApi") protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ReportFragment.injectIfNeededIn(this); }
The injectIfNeedIn method of ReportFragment is invoked in onCreate. This method actually adds a Fragment to the Activity. We know that Fragment is attached to an Activity, and the life cycle of Fragment follows the life cycle of the Activity. Since this reportfragment can sense the lifecycle of an Activity, is it responsible for distributing lifecycle events to lifecycle observer?
public class ReportFragment extends Fragment { private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle" + ".LifecycleDispatcher.report_fragment_tag"; public static void injectIfNeededIn(Activity activity) { // ProcessLifecycleOwner should always correctly work and some activities may not extend // FragmentActivity from support lib, so we use framework fragments for activities 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(); } } static ReportFragment get(Activity activity) { return (ReportFragment) activity.getFragmentManager().findFragmentByTag( REPORT_FRAGMENT_TAG); } private ActivityInitializationListener mProcessListener; private void dispatchCreate(ActivityInitializationListener listener) { if (listener != null) { listener.onCreate(); } } private void dispatchStart(ActivityInitializationListener listener) { if (listener != null) { listener.onStart(); } } private void dispatchResume(ActivityInitializationListener listener) { if (listener != null) { listener.onResume(); } } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); dispatchCreate(mProcessListener); dispatch(Lifecycle.Event.ON_CREATE); } @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; } private void dispatch(Lifecycle.Event event) { Activity activity = getActivity(); 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); } } } void setProcessListener(ActivityInitializationListener processListener) { mProcessListener = processListener; } interface ActivityInitializationListener { void onCreate(); void onStart(); void onResume(); } }
The code of reportfragment is well understood. We can find lifecycle in the code Event. XXX event and set lifecycle. In its lifecycle callback method Event. The XXX event is passed to the dispatch method, which is obviously used to distribute the life cycle. In the dispatch method of ReportFragment, the handleLifecycleEvent method of LifecycleRegistry is called:
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) { State next = getStateAfter(event); moveToState(next); }
Before analyzing this method, we need to understand the events and states of Lifecycle:
public abstract class Lifecycle { public enum Event { /** * Constant for onCreate event of the {@link LifecycleOwner}. */ ON_CREATE, /** * Constant for onStart event of the {@link LifecycleOwner}. */ ON_START, /** * Constant for onResume event of the {@link LifecycleOwner}. */ ON_RESUME, /** * Constant for onPause event of the {@link LifecycleOwner}. */ ON_PAUSE, /** * Constant for onStop event of the {@link LifecycleOwner}. */ ON_STOP, /** * Constant for onDestroy event of the {@link LifecycleOwner}. */ ON_DESTROY, /** * An {@link Event Event} constant that can be used to match all events. */ ON_ANY } public enum State { /** * Destroyed state for a LifecycleOwner. After this event, this Lifecycle will not dispatch * any more events. For instance, for an {@link android.app.Activity}, this state is reached * <b>right before</b> Activity's {@link android.app.Activity#onDestroy() onDestroy} call. */ DESTROYED, /** * Initialized state for a LifecycleOwner. For an {@link android.app.Activity}, this is * the state when it is constructed but has not received * {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} yet. */ INITIALIZED, /** * Created state for a LifecycleOwner. For an {@link android.app.Activity}, this state * is reached in two cases: * <ul> * <li>after {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} call; * <li><b>right before</b> {@link android.app.Activity#onStop() onStop} call. * </ul> */ CREATED, /** * Started state for a LifecycleOwner. For an {@link android.app.Activity}, this state * is reached in two cases: * <ul> * <li>after {@link android.app.Activity#onStart() onStart} call; * <li><b>right before</b> {@link android.app.Activity#onPause() onPause} call. * </ul> */ STARTED, /** * Resumed state for a LifecycleOwner. For an {@link android.app.Activity}, this state * is reached after {@link android.app.Activity#onResume() onResume} is called. */ RESUMED; } }
Lifecycle.Event corresponds to each declaration cycle of activity, lifecycle State is the state of lifecycle. The conversion relationship between States is defined in lifecycle registry:
public class LifecycleRegistry extends Lifecycle { static State getStateAfter(Event event) { switch (event) { case ON_CREATE: case ON_STOP: return CREATED; case ON_START: case ON_PAUSE: return STARTED; case ON_RESUME: return RESUMED; case ON_DESTROY: return DESTROYED; case ON_ANY: break; } throw new IllegalArgumentException("Unexpected event value " + event); } private static Event downEvent(State state) { switch (state) { case INITIALIZED: throw new IllegalArgumentException(); case CREATED: return ON_DESTROY; case STARTED: return ON_STOP; case RESUMED: return ON_PAUSE; case DESTROYED: throw new IllegalArgumentException(); } throw new IllegalArgumentException("Unexpected state value " + state); } 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); } }
These three methods can be summarized as the following figure:
downEvent indicates from one state to the state below it in the figure, and upEvent is upward.
After understanding the status of Lifecycle, let's continue to look at Lifecycle registry. As we know above, when the life cycle of an Activity changes, the ReportFragment will perceive it, call the dispatch method, and finally call the handlelife cycleevent method of LifecycleRegistry:
public class LifecycleRegistry extends Lifecycle { private int mAddingObserverCounter = 0; private boolean mHandlingEvent = false; private boolean mNewEventOccurred = false; public void handleLifecycleEvent(@NonNull Lifecycle.Event event) { State next = getStateAfter(event); moveToState(next); } private void moveToState(State next) { if (mState == next) { return; } mState = next; // When we trigger a state change when LifecycleRegistry calls back to LifecycleObserver, // mHandlingEvent is true; // When adding an observer, the callback method may also be executed. At this time, if a state change is triggered, // Then maddingobservercounter= 0 if (mHandlingEvent || mAddingObserverCounter != 0) { mNewEventOccurred = true; // sync is not required. // The implementation here is: sync() - > lifecycle Observer - > movetostate() // After returning directly here, you will still return to sync() and continue to synchronize to the observer // we will figure out what to do on upper level. return; } mHandlingEvent = true; // sync() converts the state changes into lifecycle events and forwards them to lifecycle observer sync(); mHandlingEvent = false; } }
What lifecycle registry is supposed to do is actually very simple, but it introduces a lot of additional complexity because it needs to execute the customer's code. The reason is that the customer code is not under our control, and they may do anything they can. For example, here, a state change is triggered in the callback. Similarly, if the client code is not called when the lock is held, the implementation will become more complex.
Next, let's look at sync():
public class LifecycleRegistry extends Lifecycle { /** * Custom list that keeps observers and can handle removals / additions during traversal. * * This Invariant is very important. It will affect the logic of sync() * 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 void sync() { LifecycleOwner lifecycleOwner = mLifecycleOwner.get(); if (lifecycleOwner == null) { Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch " + "new events from it."); return; } while (!isSynced()) { // mNewEventOccurred is to enable backwardPass/forwardPass() when the observer triggers a state change // For early return. We're just about to tune them. Set it to false here. mNewEventOccurred = false; // no need to check eldest for nullability, because isSynced does it for us. if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) { // The states of the elements in the mObserverMap are arranged non incrementally, that is, the state of the queue head is the largest // If the mState is smaller than the largest one in the queue, it indicates that an element needs to update the state // In order to maintain the Invariant of mObserverMap, we need to update the status of elements from the end of the queue to the front backwardPass(lifecycleOwner); } Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest(); // If mNewEventOccurred, it means that the customer triggered the status modification when calling backwardPass() above if (!mNewEventOccurred && newest != null && mState.compareTo(newest.getValue().mState) > 0) { forwardPass(lifecycleOwner); } } mNewEventOccurred = false; } // Judge whether synchronization is required. If the status of all observer s has been synchronized, return true; otherwise, return false private boolean isSynced() { if (mObserverMap.size() == 0) { return true; } //eldestObserverState is the earliest added observer, and newestObserverState is the latest added observer State eldestObserverState = mObserverMap.eldest().getValue().mState; State newestObserverState = mObserverMap.newest().getValue().mState; //Because we guarantee that the state of the team head > = the state of the following elements, we just need to judge the head and tail //If the state of the latest and oldest observers is inconsistent, or the current state is inconsistent with the latest state, state synchronization is required return eldestObserverState == newestObserverState && mState == newestObserverState; } }
The main function of sync() is to synchronize the states of all elements in the mObserverMap to mState. Let's continue to look at the remaining backwardPass/forwardPass:
public class LifecycleRegistry extends Lifecycle { // This comment should be the most difficult to understand in the whole class, at least for me // we have to keep it for cases: // void onStart() { // //removeObserver(this) indicates that this is a lifecycle observer // //So what we say here is that we perform the following two operations in the callback // mRegistry.removeObserver(this); // mRegistry.add(newObserver); // } // Suppose we want to go from CREATED to STARTED (that is, mState is now STARTED). // In this case, only when the new observer is set to the CREATED state, its onStart will be called // In order to get the CREATED, mParentStates are introduced here. Execute in forwardPass // When pushParentState(observer.mState), observer MState is the CREATED we need. // The case of backwardPass is similar. // newObserver should be brought only to CREATED state during the execution of // this onStart method. our invariant with mObserverMap doesn't help, because parent observer // is no longer in the map. private ArrayList<State> mParentStates = new ArrayList<>(); //The first while loop traverses the set of observers we store, //The second is to handle the event s that each state passes through private void forwardPass(LifecycleOwner lifecycleOwner) { // Start iteration from team leader 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 // Maybe the customer removed himself when calling back the customer code && mObserverMap.contains(entry.getKey()))) { pushParentState(observer.mState); //upEvent returns the event to be experienced //For example, if it is STARTED at present, the events it passes through are ON_RESUME observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState)); popParentState(); } } } private void backwardPass(LifecycleOwner lifecycleOwner) { // Start iteration at the end of the team Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator = mObserverMap.descendingIterator(); while (descendingIterator.hasNext() && !mNewEventOccurred) { Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next(); ObserverWithState observer = entry.getValue(); while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred && mObserverMap.contains(entry.getKey()))) { Event event = downEvent(observer.mState); pushParentState(getStateAfter(event)); observer.dispatchEvent(lifecycleOwner, event); popParentState(); } } } private void popParentState() { mParentStates.remove(mParentStates.size() - 1); } private void pushParentState(State state) { mParentStates.add(state); } }
Tip: refer to the above state transition diagram when looking at the forwardPass and backwardPass methods
- It is assumed that all ObserverWithState elements in the current collection are in the CREATED state. An on message is then received_ As can be seen from the figure, the next step should be to switch to the STARTED state. Since STARTED is greater than CREATED, the forwardPass method is executed. Call upEvent(observer.mState) in forwardPass to return the event to be sent from CREATED to STARTED, that is, ON_START, then on_ The start event was sent to the observer.
- Assume that the mState of the current lifecycle registry is in the resumed state. Then we call the addObserver method to add a new LifecycleObserver. The observer will be encapsulated into ObserverWithState into the collection. This new ObserverWithState is in the INITIALIZED state. Since RESUMED is greater than INITIALIZED, the forwardPass method will be implemented. The status of observerwithstate will change in the order of * * initialized - > created - > started - > resumed * *.
summary
Some personal questions:
- Doubt 1: why not directly distribute Lifecycle events to Lifecycle in the Lifecycle function of SupportActivity, but add a Fragment?
Because not all pages inherit AppCompatActivity, in order to be compatible with non AppCompatActivity, a Fragment with the same life cycle is encapsulated to distribute life cycle events to Lifecycle. Obviously, Fragment is less invasive.
- Doubt 2: why use ReportFragment to distribute the Lifecycle instead of directly using the callback of ActivityLifecycleCallbacks to handle the changes in the Lifecycle?
Because the callback of activitylifecycle callbacks is earlier than Fragment and Activity, the corresponding lifecycle method is not actually executed
This is the end of the Lifecycle analysis. Finally, a flow chart is attached to help understand and remember: