The previous core tutorial on the use of LifeCycle for Jetpack focused on the meaning of LifeCycle and the basic and advanced ways to use LifeCycle. Today, words do not say, directly began to source.
This article is based on the source code of android_9.0.0_r45 in my hand. All relevant source code including comments have been uploaded to my Github. You can clone it directly and check it against the article.
LifeCycle the three musketeers
LifecycleOwner, LifecycleObserver, Lifecycle.
LifecycleOwner is an interface, and an interface is usually used to declare a capability. LifecycleOwner’s ability is to have a lifecycle. Typical lifecycle components are activities and fragments. Of course, we can also customize life cycle components. LifecycleOwner provides the getLifecycle() method to obtain its Lifecycle object.
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle(a);
}
Copy the code
LifecycleObserver is a LifecycleObserver, which is an empty interface. It has no methods and relies on the OnLifecycleEvent annotation to receive lifecycle callbacks.
public interface LifecycleObserver {}Copy the code
Lifecycle components and Lifecycle observers are available, and Lifecycle is the bridge between them.
Lifecycle is the concrete Lifecycle object that every LifecycleOwner holds. Lifecycle allows us to capture the current Lifecycle state, add/remove Lifecycle observers, and so on.
Lifecycle defines two enumerated classes, Event and State, inside Lifecycle. An Event represents a lifecycle Event and corresponds to a LifecycleOwner’s lifecycle Event.
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
}
Copy the code
ON_ANY is special in that it represents any lifecycle event. Why design ON_ANY? Actually, I don’t know. I haven’t figured it out yet.
Another enumerated class, State, represents the life cycle State.
public enum State {
/** * Lifecycle will not dispatch Lifecycle events after this. * This state precedes activity.ondestroy () */
DESTROYED,
/**
* 在 Activity 已经实例化但未 onCreate() 之前
*/
INITIALIZED,
/** * after onCreate() and before onStop() */
CREATED,
/** * after onStart() and before onPause() */
STARTED,
/** ** after the Activity's onResume() */
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0; }}Copy the code
State can be relatively difficult to understand, especially the order of enumeration values. You will not go into detail here, but you must remember the order of the enumeration values. You must DESTROYED — INITIALIZED — CREATED — STARTED — RESUMED.
A brief review of the relationship between the three musketeers. LifecycleOwner, a lifecycle component, sends a specific lifecycle Event to notify Lifcycle to enter a specific State after entering a specific lifecycle, which in turn calls back to the LifeCycleObserver specified methods.
From the addObserver () to start
With no source code to begin with, we will start with the basic use of Lifecycle.
lifecycle.addObserver(LocationUtil( ))
Copy the code
Lifecycle is actually the getLifecycle() method, but it’s shortened in Kotlin. GetLifecycle () is a method that interfaces LifecycleOwner. AppCompatActivity doesn’t implement LifecycleOwner directly, nor does its parent FragmentActivity. LifecycleOwner can only be found in its parent ComponentActivity. Take a look at the implementation of the interface.
@Override
public Lifecycle getLifecycle(a) {
return mLifecycleRegistry;
}
Copy the code
LifeCycle mLifecycleRegistry is a LifecycleRegistry object, and LifecycleRegistry is an implementation class for LifeCycle. So LifecycleRegistry here is our lifecycle object. Take a look at its addObserver() method.
> LifecycleRegistry.java
......
// Save LifecycleObserver and its corresponding State
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
// Current life cycle status
private State mState;
/** * Add LifecycleObserver ** Also note the "backloading" of lifecycle events, if addObserver() is called in onResume(), * then, Observers can still receive onCreate and onStart events. * This is done to ensure that LifecycleObserver in the mObserverMap is always in the same state */
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// ObserverWithState is a static inner class
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
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;
}
// Determine whether to reenter
booleanisReentrance = mAddingObserverCounter ! =0 || mHandlinengEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
// Synchronize to targetState if the observer's initial state is less than targetState
while ((statefulObserver.mState.compareTo(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--;
}
Copy the code
There are two things to note here. The first problem is the lifecycle “flooding problem,” a term I borrowed from LiveData. What exactly is the problem? For example, even if you call the addObserver() method in onResume() to add an observer, the observer can still receive the onCreate and onStart events in turn, eventually synchronizing to targetState. This targetState is calculated using the calculateTargetState(observer) method.
/** * the calculated targetState must be less than or equal to */ of the current mState
private State calculateTargetState(LifecycleObserver observer) {
// Get the previous Observer of the current ObserverEntry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer); State siblingState = previous ! =null ? previous.getValue().mState : null;
ParentState is null without reentrantState parentState = ! mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() -1)
: null;
return min(min(mState, siblingState), parentState);
}
Copy the code
We can add multiple lifecycle observers, and care must be taken to maintain their state. Each time a new observer is added, the initial state is INITIALIZED, and it needs to be synchronized to the current lifecycle state — specifically, to a targetState that is no greater than the current state. The calculation method in the source code is also reflected, targetState is the current state mState, the state of the last observer in mObserverMap, and the minimum value of parentState in the case of reentrant.
Why do I want to take this minimum? My understanding is that when there is a new lifecycle event, all observers in the mObserverMap need to be synchronized to the new same state. This synchronization process may not be complete, so new observers can only be synchronized to the minimum state first. Note that in the while loop of the addObserver method, calculateTargetState() is called to recalculate targetState every time the new observer changes its life cycle.
In the final stable state, no lifecycle switches, no new observers are added, and all observers in the mObserverMap should be in the same lifecycle state.
Who distributes life cycle events?
Now that the observer is added, how do you notify the observer of life cycle changes?
Go back to ComponentActivity, and you’ll see that you haven’t overridden all of the lifecycle functions. The only thing suspicious is a line of code in onCreate().
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
if(mContentLayoutId ! =0) { setContentView(mContentLayoutId); }}Copy the code
The ReportFragment here is the answer. Follow injectIfNeededIn().
public static void injectIfNeededIn(Activity activity) {
/ / using android. App. FragmentManager compatibly
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.manager.executePendingTransactions(); }}Copy the code
This injects a Fragment into the Activity without a page. Which brings me to some dynamic permission libraries that do the same thing, injecting fragments to broker permission requests. Not surprisingly, ReportFragment is where the lifecycle is actually distributed.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart(a) {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume(a) {
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause(a) {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
@Override
public void onStop(a) {
super.onStop();
dispatch(Lifecycle.Event.ON_STOP);
}
@Override
public void onDestroy(a) {
super.onDestroy();
dispatch(Lifecycle.Event.ON_DESTROY);
// just want to be sure that we won't leak reference to an activity
mProcessListener = null;
}
Copy the code
MProcessListener deals with the application process lifecycle and is left alone.
Take a look at the dispatch() method.
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) {
/ / call LifecycleRegistry. HandleLifecycleEvent () method((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); }}}Copy the code
Lifecycle events are distributed through the Dispatch () method in each ReportFragment lifecycle function, and then handled by calling the handleLifecycleEvent() method in LifecycleRegistry. For the sake of subsequent code understanding, it is assumed that we are now going through a synchronization from onStart() to onResume(), that is, the argument in the handleLifecycleEvent() method is ON_RESUME.
// Sets the current state and notifies the observer
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
Copy the code
The purpose of getStateAfter() is to get the state after the Event based on the Event and inform the observer to synchronize to this lifecycle state.
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);
}
Copy the code
The argument is ON_RESUME, so the state you need to synchronize to is RESUMED. Now look at the logic of the moveToState() method.
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
First, the lifecycle state to be synchronized is assigned to the current lifecycle state, mState, where the value of mState is RESUMED. The sync() method is then called to synchronize the state of all observers.
private void sync(a) {
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 =false;
// mState is the current state. If mState is less than the state value in mObserverMap, call backwardPass().
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
// If mState is greater than the state value in mObserverMap, call forwardPass()
if(! mNewEventOccurred && newest ! =null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
Copy the code
This compares the State value of the observer in the mState and mObserverMap to determine whether the State needs to be synchronized forward or backward. Now the value of mState is RESUMED, and the observer is still in the previous state STARTED, so all of the observer’s state has to go one step forward. The forwardPass() method is called.
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();// Pass events up until the observer state value equals the current state value
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
// Distribute lifecycle eventsobserver.dispatchEvent(lifecycleOwner, upEvent(observer.mState)); popParentState(); }}}Copy the code
ForwardPass () synchronizes all observers in the mObserverMap to the specified life cycle state, and if the span is large, the intermediate state is distributed in turn. Distributing life cycle events ultimately relies on the dispatchEvent() method of ObserverWithState.
Here to pause the archive, do not continue to follow the source code. The scenario assumed above is the ON_START to ON_RESUME process. Now imagine another scenario where I just press the Home button to go back to the desktop, and the current Activity’s life cycle goes from onResumed to onPaused as follows.
-
Lifecycle.Event.ON_PAUSE ReportFragment calls dispatch(Lifecycle
-
Call LifecycleRegistry. HandleLifecycleEvent () method, parameter is ON_PAUSE
-
GetStateAfter () gets that the state to synchronize to is STARTED, assigns it to mState, and then calls moveToState()
-
Call sync() in moveToState(Lifecycle.state. STARTED) to synchronize
-
In the sync() method, the value of mState is STARTED, while in the mObserverMap the observer is all RESUMED. So the observers all need to step back, which calls the backwardPass() method.
The backwardPass() method is pretty much the same as forwardPass().
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();// Events are passed down until the observer state value equals the current state value
while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
Event event = downEvent(observer.mState);
pushParentState(getStateAfter(event));
// Distribute lifecycle eventsobserver.dispatchEvent(lifecycleOwner, event); popParentState(); }}}Copy the code
The only difference is to get the event to distribute, which is upEvent() and downEvent().
UpEvent () is the event that needs to be experienced to get the state upgrade, and downEvent() is the event that needs to be experienced to get the state downgrade.
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);
}
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);
}
Copy the code
From STARTED to RESUMED, the return value of upEvent(STARTED) is ON_RESUME. To degrade from RESUMED to STARTED, downEvent(RESUMED) returns ON_PAUSE.
I don’t know if you are confused. It took me a long time to figure out the relationship between State and Event. Remember the enumeration order of State first?
DESTROYED —— INITIALIZED —— CREATED —— STARTED —— RESUMED
Copy the code
They DESTROYED the code. OnResume enters the onPause phase and the last lifecycle event that is issued is indeed ON_PAUSE, but sets the observer’s state to STARTED. Why is that?
As for the relationship between State and Event, the official website provides a graph as follows:
But I have to say, it’s a little abstract, and I should have drawn it differently. Here’s another picture I saw here:
Is there a sense of the events between the states, the states after the events, the sizes between the states? It is important to understand this picture because without understanding the relationship between Event and State Lifecycle will not be understood.
Who calls back and forth your annotation methods?
Reading back from the pause archive, the sync() method that synchronised the Observer life cycle would eventually call the dispatchEvent() method of ObserverWithState.
static class ObserverWithState {
State mState;
GenericLifecycleObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
// ReflectiveGenericLifecycleObserver.onStateChanged()mLifecycleObserver.onStateChanged(owner, event); mState = newState; }}Copy the code
The mLifecycleObserver is assigned by Lifecycling. GetCallback ().
@NonNull
static GenericLifecycleObserver getCallback(Object object) {
if (object instanceof FullLifecycleObserver) {
return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
}
if (object instanceof GenericLifecycleObserver) {
return (GenericLifecycleObserver) object;
}
finalClass<? > klass = object.getClass();int type = getObserverConstructorType(klass);
/ / get the type
// GENERATED_CALLBACK represents the code generated by the annotation
// REFLECTIVE_CALLBACK indicates that reflection is used
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);
}
return new ReflectiveGenericLifecycleObserver(object);
}
Copy the code
If DefaultLifecycleObserver is used and DefaultLifecycleObserver inherits from FullLifecycleObserver, So it will be returned FullLifecycleObserverAdapter.
If only the ordinary LifecycleObserver, you will need to pass getObserverConstructorType () method to determine the use of annotations or reflection.
private static int getObserverConstructorType(Class
klass) {
if (sCallbackCache.containsKey(klass)) {
return sCallbackCache.get(klass);
}
int type = resolveObserverCallbackType(klass);
sCallbackCache.put(klass, type);
return type;
}
private static int resolveObserverCallbackType(Class
klass) {
// anonymous class bug:35073837
// Anonymous inner classes use reflection
if (klass.getCanonicalName() == null) {
return REFLECTIVE_CALLBACK;
}
// Find the GeneratedAdapter class generated by the annotation
Constructor<? extends GeneratedAdapter> constructor = generatedConstructor(klass);
if(constructor ! =null) {
sClassToAdapters.put(klass, Collections
.<Constructor<? extends GeneratedAdapter>>singletonList(constructor));
return GENERATED_CALLBACK;
}
// Find methods annotated by OnLifecycleEvent
boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass);
if (hasLifecycleMethods) {
return REFLECTIVE_CALLBACK;
}
// The annotation generated by the GeneratedAdapter class was not found, and the OnLifecycleEvent annotation was not found,
// Look up for the parent classClass<? > 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));
}
// Find if there is an interface implementation
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;
}
Copy the code
Notice the hasLifecycleMethods() method.
boolean hasLifecycleMethods(Class klass) {
if (mHasLifecycleMethods.containsKey(klass)) {
return mHasLifecycleMethods.get(klass);
}
Method[] methods = getDeclaredMethods(klass);
for (Method method : methods) {
OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
if(annotation ! =null) {
createInfo(klass, methods);
return true;
}
}
mHasLifecycleMethods.put(klass, false);
return false;
}
Copy the code
This is going to look for the OnLifecycleEvent annotation. So the MyObserver we implement through the OnLifecycleEvent annotation is of type REFLECTIVE_CALLBACK, which means to use reflection calls. Note that another type, GENERATED_CALLBACK, represents code generated using annotations, not reflection.
So, so, **Lifecycle can choose to use APT compile time to generate code to avoid using runtime reflection in order to optimize performance? ** seems to be the case. Which brings me to EventBus’s index acceleration is also turned off by default. See, that’s the beauty of reading source code, always finding your own blind spots. Add the following dependencies to speed LifeCycle!
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
Copy the code
For the sake of parsing, let’s go back to the reflection call.
Our own definition in ordinary observer invocation is ReflectiveGenericLifecycleObserver onStateChanged ().
class ReflectiveGenericLifecycleObserver implements GenericLifecycleObserver {
private final Object mWrapped; / / the Observer object
private final CallbackInfo mInfo; // reflection gets annotation information
ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}
@Override
public void onStateChanged(LifecycleOwner source, Event event) {
/ / call ClassesInfoCache. CallbackInfo. InvokeCallbacks ()mInfo.invokeCallbacks(source, event, mWrapped); }}Copy the code
Chased again into ClassesInfoCache. CallbackInfo. InvokeCallbacks () method.
void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
// Not only the current lifecycle events are distributed, but also ON_ANY
invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,
target);
}
private static void invokeMethodsForEvent(List
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); }}}void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
//noinspection TryWithIdenticalCatches
try {
switch (mCallType) {
case CALL_TYPE_NO_ARG:
mMethod.invoke(target);
break;
case CALL_TYPE_PROVIDER:
mMethod.invoke(target, source);
break;
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 newRuntimeException(e); }}Copy the code
It’s as simple as that. Reflection calls the lifecycle callback method of the OnLifecycleEvent annotation tag.
Wait For More
I would have liked to continue analyzing the source code for ProcessLifecycleOwner and coroutines for Lifecycle, but this article is a bit too long, so I’ll leave it to the next article.
References and recommendations
The following articles are equally excellent, read them carefully and recommend them to you.
- The beauty of Android architecture -Lifecycle
- Jetpack and LifeCycle (3)
- Android-lifecycle will be able to parse the Android Lifecycle
This article first published wechat official account: BingxinshuaiTM, focusing on Java, Android original knowledge sharing, LeetCode problem solving.
More latest original articles, scan code to pay attention to me!