Lifecycle is introduced

Lifecycle can turn a class into an Activity or Fragment Lifecycle observer class that listens for changes in its Lifecycle and can respond to them. Lifecycle makes code more organized, streamlined and easy to maintain.

There are two main roles in Lifecycle:

  • LifecycleOwner: Lifecycle owners, such as Activity/Fragment classes, implement this interface and obtain Lifecycle via getLifecycle(), which in turn adds observers via addObserver().
  • LifecycleObserver: LifecycleObserver. Once implemented, this interface can be added to Lifecycle to be notified immediately of changes to the observed class Lifecycle.

Lifecycle owners that implement LifecycleOwner can work perfectly with observers that implement LifecycleObserver.

Scene: the case

Suppose we have an Activity that displays the location of the device on the screen, we might implement it like this:

internal class MyLocationListener(
        private val context: Context,
        private val callback: (Location) -> Unit) {

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

    fun stop() {
        // disconnect from system location service
    }
}

class MyActivity : AppCompatActivity() {
    private lateinit var myLocationListener: MyLocationListener

    override fun onCreate(...) {
        myLocationListener = MyLocationListener(this) { location ->
            // update UI
        }
    }

    public override fun onStart() {
        super.onStart()
        myLocationListener.start()
        // manage other components that need to respond
        // to the activity lifecycle
    }

    public override fun onStop() {
        super.onStop()
        myLocationListener.stop()
        // manage other components that need to respond
        // to the activity lifecycle
    }
}
Copy the code

Note: The above code is from the official example ~

We can operate directly on dependent components in the Activity or Fragment lifecycle methods (onStart/onStop in the example). However, this can lead to poorly organized and extensible code. With Lifecycle, then, component-dependent code can be moved from Activity/Fragment Lifecycle methods into the component itself.

Lifecycle using

Build. Gradle:

Allprojects {repositories {Google () // For Gradle < 4.1, replace it with the following declaration: // maven { // url 'https://maven.google.com' // } // An alternative URL is 'https://dl.google.com/dl/android/maven2/' } }Copy the code

Under the app build. Gradle:

Dependencies {def lifecycle_version = "2.3.1" def arch_version = "2.1.0 "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" // LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version" // Lifecycles only (without ViewModel or LiveData) implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" // Saved state module for ViewModel implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version" // Annotation processor kapt "Androidx. Lifecycle: lifecycle - compiler: $lifecycle_version" / / optional - if you use Java8, use the following instead of lifecycle - compiler implementation "Androidx. Lifecycle: lifecycle - common - java8: $lifecycle_version" / / optional - used in the Service lifecycle implementation "Androidx. Lifecycle: lifecycle - service: $lifecycle_version" / / optional - used in Application lifecycle implementation "Androidx. Lifecycle: lifecycle - process: $lifecycle_version" / / optional - ReactiveStreams support for LiveData implementation "Androidx. Lifecycle: lifecycle - reactivestreams - KTX: $lifecycle_version" / / optional - Test helpers for LiveData testImplementation "androidx.arch.core:core-testing:$arch_version" }Copy the code

Lifecycle is used in activities/fragments

LifecycleObserver implementation first:

open class MyLifeCycleObserver : LifecycleObserver {

    @OnLifecycleEvent(value = Lifecycle.Event.ON_START)
    fun connect(owner: LifecycleOwner) {
        Log.e(JConsts.LIFE_TAG, "Lifecycle.Event.ON_CREATE:connect")
    }

    @OnLifecycleEvent(value = Lifecycle.Event.ON_STOP)
    fun disConnect() {
        Log.e(JConsts.LIFE_TAG, "Lifecycle.Event.ON_DESTROY:disConnect")
    }
}
Copy the code

For the method, we use the @onlifecycleEvent annotation and pass in a lifecycle event that can be of type ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY, or ON_ANY. The first six correspond to lifecycle callbacks in the Activity, and the last ON_ANY can match any lifecycle callbacks. Therefore, the connect() and disConnect() methods in the above code should be executed when the Activity’s onStart() and onStop() methods are triggered, respectively. To implement our Activity:

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onCreate") lifecycle. AddObserver (MyLifeCycleObserver())} Override fun onStart() { Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onStart") super.onStart() } override fun onResume() { Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onResume") super.onResume() } override fun onPause() { Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onPause") super.onPause() } override fun onStop() { Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onStop") super.onStop() } override fun onDestroy() { Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onDestroy") super.onDestroy() } }Copy the code

You can see that in the Activity we just added this line of code to onCreate() :

lifecycle.addObserver(MyLifeCycleObserver())
Copy the code

Where getLifecycle() is a method in LifecycleOwner that returns Lifecycle objects and adds our Lifecycle observer via addObserver(). To see the result, start the Activity:

2021-06-30 20:57:58.038 11257-11257/ E/Lifecycle_Study: ACTIVITY:onCreate Connect () 2021-06-30 20:57:58.048 11257-11257/ E/Lifecycle_Study: ACTIVITY:onStart 2021-06-30 20:57:58.049 11257-11257/ E/Lifecycle_Study: Lifecycle.event. ON_START:connect 2021-06-30 20:57:58.057 11257-11257/ E/Lifecycle_Study: ACTIVITY:onResumeCopy the code

Shut down the Activity:

646 11257-11257/ E/Lifecycle_Study: ACTIVITY:onPause //onStop() pass to MyLifeCycleObserver: DisConnect () 2021-06-30 20:58:03.149 11257-11257/ E/Lifecycle_Study: ACTIVITY:onStop 2021-06-30 20:58:03.161 11257-11257/ E/Lifecycle_Study: ON_STOP:disConnect 2021-06-30 20:58:03.169 11257-11257/ E/Lifecycle_Study: ACTIVITY:onDestroyCopy the code

You can see that the connect()/disconnect() methods in our MyLifeCycleObserver are indeed executed separately during the onStart()/onStop() callback of the Activity.

Custom LifecycleOwner

LifecycleOwner is implemented by the Activity and Fragmen in AndroidX, and Lifecycle(which is an abstract class instantiated by subclass LifecycleRegistry) can be obtained by getLifecycle().

public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle();
}

public class LifecycleRegistry extends Lifecycle {

}
Copy the code

If we wanted a custom class to be LifecycleOwner, we could implement LifecycleOwner directly:

class CustomLifeCycleOwner : LifecycleOwner { private lateinit var registry: LifecycleRegistry Fun init() {registry = LifecycleRegistry(this) // Use setCurrentState to complete the lifecycle pass registry.currentState = Lifecycle.State.CREATED } fun onStart() { registry.currentState = Lifecycle.State.STARTED } fun onResume() { registry.currentState = Lifecycle.State.RESUMED } fun onPause() { registry.currentState = Lifecycle.State.STARTED } fun onStop() { registry.currentState = Lifecycle.State.CREATED } fun onDestroy() { registry.currentState = Lifecycle. State. DESTROYED} override fun getLifecycle () : Lifecycle {/ / return return LifecycleRegistry instance registry}}Copy the code

First, our custom class implements the interface LifecycleOwner and returns the LifecycleRegistry instance in getLifecycle(). We can then pass the lifecycle state through LifecycleRegistry#setCurrentState. So far, most of the work has been done, and the last thing you need to do is add a LifecycleObserver:

Class MainActivity: Activity() {val owner: CustomLifeCycleOwner = CustomLifeCycleOwner() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onCreate") // Customize LifecycleOwner owner.init() // Add LifecycleObserver owner.lifecycle.addObserver(MyLifeCycleObserver()) } override fun onStart() { Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onStart") super.onStart() owner.onStart() } override fun onResume() { Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onResume") super.onResume() owner.onResume() } override fun onPause() { Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onPause") super.onPause() owner.onPause() } override fun onStop() { Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onStop") super.onStop() owner.onStop() } override fun onDestroy() { Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onDestroy") super.onDestroy() owner.onDestroy() } }Copy the code

Very simple, basically instantiating LifecycleOwner in onCreate() and calling init() to complete the LifecycleRegistry instantiation. LifecycleRegistry instance is obtained via getLifecycle() and lifecycleGistry Observer is registered via addObserver(), just like the Activity in androidX. No more repeated pastes.

Lifecycle is used in the Application

First remember to introduce corresponding dependencies:

implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
Copy the code

Then the code is written as follows:

//MyApplicationLifecycleObserver.kt
class MyApplicationLifecycleObserver : LifecycleObserver {

    @OnLifecycleEvent(value = Lifecycle.Event.ON_START)
    fun onAppForeground() {
        Log.e(JConsts.LIFE_APPLICATION_TAG, "onAppForeground")
    }

    @OnLifecycleEvent(value = Lifecycle.Event.ON_STOP)
    fun onAppBackground() {
        Log.e(JConsts.LIFE_APPLICATION_TAG, "onAppBackground")
    }
}

//MyApplication.kt
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(MyApplicationLifecycleObserver())
    }
}

//manifest.xml
<application
   android:name=".MyApplication">
</application>
Copy the code

Start the app:

2021-06-30 21:55:11.657 14292-14292/ E/Lifecycle_App_Study: onAppForeground
Copy the code

Hit the Home button to cut the app to the background:

2021-06-30 21:55:35.741 14292-14292/ E/Lifecycle_App_Study: onAppBackground
Copy the code

Cut back:

2021-06-30 21:55:11.657 14292-14292/ E/Lifecycle_App_Study: onAppForeground
Copy the code

ProcessLifecycleOwner can easily help us detect the state of the App in the foreground and background.

Lifecycle is used in a Service

Using Lifecycle in a Service also requires the introduction of a dependency:

implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
Copy the code

Then inherit LifecycleService:

//MyService.kt class MyService : LifecycleService() { override fun onCreate() { Log.e(JConsts.SERVICE, "Service:onCreate") super.onCreate() lifecycle.addObserver(MyLifeCycleObserver()) } override fun onStart(intent: Intent? , startId: Int) { Log.e(JConsts.SERVICE, "Service:onStart") super.onStart(intent, startId) } override fun onDestroy() { Log.e(JConsts.SERVICE, "Service:onDestroy") super.ondestroy ()}} // mainActivity.kt /** * Start Service */ private Fun startLifecycleService() { Intents = intents (this, MyService::class.java) startService(intents)} View) { val intent = Intent(this, MyService::class.java) stopService(intent) }Copy the code

LifecycleService implements the LifecycleOwner interface, so subclasses can add a lifecycle Observer directly via getLifecycle() and start a Service in the Activity:

2021-07-01 14:10:09.703 7606-7606/ E/SERVICE: SERVICE: onCreate 2021-07-01 14:10:09.709 7606-7606/ E/SERVICE: 712 7606-7606/ E/ Service: Lifecycle.Event.ON_START:connectCopy the code

Operation stop Service:

2021-07-01 14:10:13.062 7606-7606/ E/SERVICE: SERVICE: onDestroy 2021-07-01 14:10:13.063 7606-7606/ E/SERVICE: Lifecycle.Event.ON_STOP:disConnectCopy the code

The result is also very simple, one thing to note here: Service does not have onPause/onStop, so after Service#onDestroy(), LifecycleService will distribute both Lifecycle.Event.ON_STOP and Lifecycle.

Full code address

See the Jetpack Lifecycle example for the full code address

The source code parsing

Lifecycle.java

public abstract class Lifecycle { @NonNull AtomicReference<Object> mInternalScopeRef = new AtomicReference<>(); @MainThread public abstract void addObserver(@NonNull LifecycleObserver observer); @MainThread public abstract void removeObserver(@NonNull LifecycleObserver observer); @MainThread @NonNull public abstract State getCurrentState(); // Lifecycle events corresponding to the Activity/Fragment lifecycle public enum Event {ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY, /** * An constant that can be used to match all events. */ ON_ANY} // Lifecycle status public enum State {// after onStop(), This state is the LifecycleOwner final state, Lifecycle will not distribute Event DESTROYED, // INITIALIZED INITIALIZED, // CREATED after onCreate() or onStop(), // STARTED after onStart() or onPause(), / / onResume () after RESUMED; public boolean isAtLeast(@NonNull State state) { return compareTo(state) >= 0; }}}Copy the code

Two important enumerations in Lifecycle:

  • Event: life cycle events, includingON_CREATE,ON_START,ON_RESUME,ON_PAUSE,ON_STOP,ON_DESTROY,ON_ANYCorresponding toActivity/FragmentLife cycle.
  • State: indicates the life cycle statusDESTROYED,INITIALIZED,CREATED,STARTED,RESUMED.EventThe change will makeStateIt has changed.

The relationship is as follows:

Event Life cycle events are distributed and received

Compatactivity inherits from AppCompatActivity, so go on to find any parent of AppCompatActivity and find ComponentActivity:

Public class ComponentActivity extends androidx.core.app.Com ponentActivity implements LifecycleOwner {/ / omit other code Private Final LifecycleRegistry = new LifecycleRegistry(this); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); / / the events of life cycle to ReportFragment ReportFragment. InjectIfNeededIn (this); if (mContentLayoutId ! = 0) { setContentView(mContentLayoutId); } } } @CallSuper @Override protected void onSaveInstanceState(@NonNull Bundle outState) { Lifecycle lifecycle = getLifecycle(); if (lifecycle instanceof LifecycleRegistry) { ((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED); } super.onSaveInstanceState(outState); mSavedStateRegistryController.performSave(outState); } @NonNull @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; }}Copy the code

You can see that getLifecycle() returns a LifecycleRegistry instance and that onSaveInstanceState() dispenses the Lifecycle.state.created State, but the other Lifecycle callbacks aren’t there, huh? Take a look again, the onCreate (). A ReportFragment injectIfNeededIn (this), direct check:

public class ReportFragment extends Fragment { private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle" + ".LifecycleDispatcher.report_fragment_tag"; public static void injectIfNeededIn(Activity activity) { if (Build.VERSION.SDK_INT >= 29) { activity.registerActivityLifecycleCallbacks( new LifecycleCallbacks()); } 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(); } } @SuppressWarnings("deprecation") static void dispatch(@NonNull Activity activity, @nonnull Lifecycle.Event Event) {// Has been marked as @deprecated 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); } } } static ReportFragment get(Activity activity) { return (ReportFragment) activity.getFragmentManager().findFragmentByTag( REPORT_FRAGMENT_TAG); } @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(@NonNull Lifecycle.Event event) { if (Build.VERSION.SDK_INT < 29) { dispatch(getActivity(), event); }} / / API29 and above directly using the Application. The ActivityLifecycleCallbacks to listen on the static life cycle class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks { @Override public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) { } @Override public void onActivityPostCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { dispatch(activity, Lifecycle.Event.ON_CREATE); } @Override public void onActivityStarted(@NonNull Activity activity) { } @Override public void onActivityPostStarted(@NonNull Activity activity) { dispatch(activity, Lifecycle.Event.ON_START); } @Override public void onActivityResumed(@NonNull Activity activity) { } @Override public void onActivityPostResumed(@NonNull Activity activity) { dispatch(activity, Lifecycle.Event.ON_RESUME); } @Override public void onActivityPrePaused(@NonNull Activity activity) { dispatch(activity, Lifecycle.Event.ON_PAUSE); } @Override public void onActivityPaused(@NonNull Activity activity) { } @Override public void onActivityPreStopped(@NonNull Activity activity) { dispatch(activity, Lifecycle.Event.ON_STOP); } @Override public void onActivityStopped(@NonNull Activity activity) { } @Override public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) { } @Override public void onActivityPreDestroyed(@NonNull Activity activity) { dispatch(activity, Lifecycle.Event.ON_DESTROY); } @Override public void onActivityDestroyed(@NonNull Activity activity) { } } }Copy the code

The logic of the code is clear, distributing life cycle events primarily through a transparent Fragment that is invasive-free to the Activity. Logic is divided into two parts: when API > = 29, directly using the Application. The ActivityLifecycleCallbacks to distribute life cycle events; When the API<29, event distribution occurs in the Fragment’s lifecycle callback. Both end up in the dispatch(Activity Activity, Lifecycle.Event Event) method, LifecycleRegistry#handleLifecycleEvent(event) is called inside the method, and we continue to look at the implementation of this method:

//LifecycleRegistry.java public void handleLifecycleEvent(@NonNull Lifecycle.Event event) { State next = getStateAfter(event); moveToState(next); } 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 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; }Copy the code

getStateAfter()According to incomingEventreturnState, such asON_CREATE, ON_STOPAnd then the correspondingCREATED, here again before this picture posted out at a glance:getstateAfter passing inmoveToState()Does some checking inside the method, and then goes tosync()In:

/** * 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 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); } Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest(); if (! mNewEventOccurred && newest ! = null && mState.compareTo(newest.getValue().mState) > 0) { forwardPass(lifecycleOwner); } } mNewEventOccurred = false; } private boolean isSynced() { if (mObserverMap.size() == 0) { return true; } State eldestObserverState = mObserverMap.eldest().getValue().mState; State newestObserverState = mObserverMap.newest().getValue().mState; // The current state is the same as the latest state (the state passed in is the same as the state in the queue). Return eldestObserverState == newestObserverState &&mState == newestObserverState; } 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); observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState)); popParentState(); } } } private void backwardPass(LifecycleOwner lifecycleOwner) { 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(); }}}Copy the code

FastSafeIterableMap< LifecycleObserver, ObserverWithState> implements safe additions and deletions during traversal. LifecycleObserver is the observer, and ObserverWithState is the encapsulation of the observer. IsSynced () is used to judge whether all observer states have been synchronized. If the new and old states in the queue are inconsistent or the State passed in is inconsistent with that in the queue, it will continue to enter the while loop. If the State passed in is less than the maximum State in the queue, BackwardPass () synchronizes all observers in the queue that are larger than the current state to the current state; If there are any observers in the queue whose state is less than the current state, then all observers in the queue whose state is less than the current state are synchronized to the current state through forwardPass(). The synchronization process is executed to the ObserverWithState#dispatchEvent() method:

static class ObserverWithState { State mState; LifecycleEventObserver mLifecycleObserver; ObserverWithState(LifecycleObserver observer, State initialState) { mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer); mState = initialState; } void dispatchEvent(LifecycleOwner owner, Event event) { State newState = getStateAfter(event); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; }}Copy the code

ObserverWithState# dispatchEvent () calls the mLifecycleObserver. OnStateChanged (), Is this mLifecycleObserver LifecycleEventObserver type (parent class is the interface LifecycleObserver), through Lifecycling. In the method of constructing LifecycleEventObserver (), Eventually return ReflectiveGenericLifecycleObserver:

//ReflectiveGenericLifecycleObserver.java class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver { private final Object mWrapped; private final CallbackInfo mInfo; ReflectiveGenericLifecycleObserver(Object wrapped) { mWrapped = wrapped; mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass()); } @Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) { mInfo.invokeCallbacks(source, event, mWrapped); }}Copy the code

ClassesInfoCache stores the callback information of all observers. CallbackInfo is the callback information of the current observer. GetInfo () returns a callback from mCallbackMap. Otherwise, the annotation OnLifecycleEvent corresponds to a method that is internally parsed by createInfo() and ultimately returns a CallbackInfo.

//ClassesInfoCache.java CallbackInfo getInfo(Class<? > klass) { CallbackInfo existing = mCallbackMap.get(klass); if (existing ! = null) { return existing; } existing = createInfo(klass, null); return existing; } private void verifyAndPutHandler(Map<MethodReference, Lifecycle.Event> handlers, MethodReference newHandler, Lifecycle.Event newEvent, Class<? > klass) { Lifecycle.Event event = handlers.get(newHandler); if (event == null) { handlers.put(newHandler, newEvent); } } private CallbackInfo createInfo(Class<? > klass, @Nullable Method[] declaredMethods) { Class<? > superclass = klass.getSuperclass(); Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>(); if (superclass ! = null) { CallbackInfo superInfo = getInfo(superclass); if (superInfo ! = null) { handlerToEvent.putAll(superInfo.mHandlerToEvent); } } Class<? >[] interfaces = klass.getInterfaces(); for (Class<? > intrfc : interfaces) { for (Map.Entry<MethodReference, Lifecycle.Event> entry : getInfo( intrfc).mHandlerToEvent.entrySet()) { verifyAndPutHandler(handlerToEvent, entry.getKey(), entry.getValue(), klass); } } Method[] methods = declaredMethods ! = null ? declaredMethods : getDeclaredMethods(klass); boolean hasLifecycleMethods = false; // Find the corresponding Method for the OnLifecycleEvent annotation. methods) { OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class); if (annotation == null) { continue; } hasLifecycleMethods = true; Class<? >[] params = method.getParameterTypes(); int callType = CALL_TYPE_NO_ARG; if (params.length > 0) { callType = CALL_TYPE_PROVIDER; // The first method argument must be LifecycleOwner if (! params[0].isAssignableFrom(LifecycleOwner.class)) { throw new IllegalArgumentException( "invalid parameter type. Must be  one and instanceof LifecycleOwner"); } } Lifecycle.Event event = annotation.value(); if (params.length > 1) { callType = CALL_TYPE_PROVIDER_WITH_EVENT; Lifecycle.Event if (! params[1].isAssignableFrom(Lifecycle.Event.class)) { throw new IllegalArgumentException( "invalid parameter type. second  arg must be an event"); } // When there are 2 arguments, the annotation must be Lifecycle.event. ON_ANY if (Event! = Lifecycle.Event.ON_ANY) { throw new IllegalArgumentException( "Second arg is supported only for ON_ANY value"); } } if (params.length > 2) { throw new IllegalArgumentException("cannot have more than 2 params"); } MethodReference methodReference = new MethodReference(callType, method); verifyAndPutHandler(handlerToEvent, methodReference, event, klass); } CallbackInfo info = new CallbackInfo(handlerToEvent); mCallbackMap.put(klass, info); mHasLifecycleMethods.put(klass, hasLifecycleMethods); return info; } //CallbackInfo.java static class CallbackInfo { final Map<Lifecycle.Event, List<MethodReference>> mEventToHandlers; final Map<MethodReference, Lifecycle.Event> mHandlerToEvent; CallbackInfo(Map<MethodReference, Lifecycle.Event> handlerToEvent) { mHandlerToEvent = handlerToEvent; mEventToHandlers = new HashMap<>(); for (Map.Entry<MethodReference, Lifecycle.Event> entry : handlerToEvent.entrySet()) { Lifecycle.Event event = entry.getValue(); List<MethodReference> methodReferences = mEventToHandlers.get(event); if (methodReferences == null) { methodReferences = new ArrayList<>(); mEventToHandlers.put(event, methodReferences); } methodReferences.add(entry.getKey()); } } void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) { invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target); invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event, target); } private static void invokeMethodsForEvent(List<MethodReference> handlers, LifecycleOwner source, Lifecycle.Event event, Object mWrapped) { if (handlers ! = null) { for (int i = handlers.size() - 1; i >= 0; i--) { handlers.get(i).invokeCallback(source, event, mWrapped); }}}Copy the code

MethodReference#invokeCallback() :

//MethodReference.java static class MethodReference { final int mCallType; final Method mMethod; MethodReference(int callType, Method method) { mCallType = callType; mMethod = method; mMethod.setAccessible(true); } void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {// noInspection trywithidenticaltodaycatch try {//OnLifecycleEvent annotation corresponding method entry switch (mCallType) {// No parameters case CALL_TYPE_NO_ARG: mMethod.invoke(target); break; // One argument: LifecycleOwner case CALL_TYPE_PROVIDER: mmethod.invoke (target, source); break; // Two arguments: LifecycleOwner, Event case CALL_TYPE_PROVIDER_WITH_EVENT: mmethod.invoke (target, source, Event); break; } } catch (InvocationTargetException e) { throw new RuntimeException("Failed to call observer method", e.getCause()); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() ! = o.getClass()) { return false; } MethodReference that = (MethodReference) o; return mCallType == that.mCallType && mMethod.getName().equals(that.mMethod.getName()); } @Override public int hashCode() { return 31 * mCallType + mMethod.getName().hashCode(); }}Copy the code

The lifecycle Event in LifecycleOwner passes from the lifecycle Event in LifecycleOwner to the corresponding method in LifecycleObserver by initializing and executing observer methods based on the number of input arguments. LifecycleOwner subclass LifecycleRegistry adds an observer:

//LifecycleRegistry.java @Override public void addObserver(@NonNull LifecycleObserver observer) { State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); // Key is LifecycleObserver,value is ObserverWithState ObserverWithState Previous = mobServerMap. putIfAbsent(observer, statefulObserver); // If it already exists, return 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; // targetState State targetState = calculateTargetState(observer); mAddingObserverCounter++; // loop through, While in the continuous synchronization to the target State Observer ((statefulObserver.mState.com pareTo (targetState) < 0 && mObserverMap. Contains (Observer))) {  pushParentState(statefulObserver.mState); statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState)); popParentState(); // mState / subling may have been changed recalculate targetState = calculateTargetState(observer); } if (! isReentrance) { // we do sync only on the top level. sync(); } mAddingObserverCounter--; } private State calculateTargetState(LifecycleObserver observer) { Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer); State siblingState = previous ! = null ? previous.getValue().mState : null; State parentState = ! mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1) : null; return min(min(mState, siblingState), parentState); }Copy the code

Add an observer and passwhileLoop will be up to dateStateState is continuously synchronized toObserver, although possible to addObserverthanLifecyleOwnerEvents are distributed late, but all events are still received, similar to the sticky events of the event bus. Finally, draw the overall class diagram:

reference

【 1 】 developer.android.com/topic/libra… [2] Android architecture component LifecycleRegistry source code analysis