1. What are Lifecycles
There is a very important concept in Jetpack: life cycles such as LiveData and ViewMode, which depend on life cycles. Common components with a life cycle are, of course, activities and fragments. Lifecycles are Activity/Fragment life-cycle aware components that hold life-cycle state information and are the core foundation of Jetpack.
2. The basic use of Lifecycle
Lifecycle is a life-cycle aware component, so its basic use is to get the life-cycle state of an Activity/Fragment.
- Import dependence
/ / lifecycle components depend on implementation 'androidx. Lifecycle: lifecycle - common: 2.2.0'Copy the code
The first way: Implement LifecycleObserver and capture the lifecycle state via annotations.
class MyLifecycleObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart(@NotNull owner: LifecycleOwner) {
Log.i("MyLifecycleObserver", "activity onStart")
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onStop() {
Log.i("MyLifecycleObserver", "activity onStop")
}
}
Copy the code
The second way: Implement LifecycleEventObserver and get the lifecycle state via the onStateChanged callback.
Mylifecycleeventobserver2: LifecycleEventObserver {override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) { when (event) { Lifecycle.Event.ON_START -> { Log.i("MyLifecycleObserver2", "activity onStart: $event") } Lifecycle.Event.ON_STOP -> { Log.i("MyLifecycleObserver2", "activity onStop: $event") } } } }Copy the code
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) lifecycle.addObserver(MyLifecycleObserver()) lifecycle.addObserver(MyLifecycleObserver2()) } }Copy the code
Start the Activity, and then close the retrieved lifecycle condition:
. I/MyLifecycleObserver: activity onStart ... I/MyLifecycleObserver2: activity onStart: ON_START ... I/MyLifecycleObserver2: activity onStop: ON_STOP ... I/MyLifecycleObserver: activity onStopCopy the code
Lifecycle source code parsing
3.1 Key classes for Lifecycle
LifecycleOwner
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
Copy the code
This is an interface that must be implemented to retrieve its lifecycle state. The current implementation classes for activities and fragments are:
Lifecycle
public abstract class Lifecycle {
}
Copy the code
An abstract class that defines enumerations of life-cycle states, as well as enumerations of distribution states. LifecycleRegistry
Public class LifecycleRegistry extends Lifecycle {// Register an Observer public void addObserver(@nonnull LifecycleObserver Observer) {} // Issue Lifecycle events public void handleLifecycleEvent(@nonnull Lifecycle.Event Event) {} private void moveToState(State next) { sync() } private void sync() {} }Copy the code
Lifecycle is the only implementation class that is primarily used to register observers and distribute Lifecycle state to observers.
3.2. Key methods
addObserver()
Override public void addObserver(@nonnull LifecycleObserver observer) {Override public void addObserver(@nonnull LifecycleObserver observer) {// 1. enforceMainThreadIfNeeded("addObserver"); // Check the state of the current host (Activity/Fragment). If the state is Destory, the original state is Destory. Everything else is Init, which means the current host is Destory, and the initial state is Destory. Everything else is init regardless of the state of the host. The state will be synchronized later. State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; // wrap the incoming observer as ObserverWithState. For synchronization and distribution of state. ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); // check whether statefulObserver already has a mObserverMap. ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver); // If the statefulObserver already exists, return if (previous! = null) { return; } // get the host LifecycleOwner object and judge LifecycleOwner = mlifecycleowner.get (); If (lifecycleOwner == null) {// It is null we should be destroyed. Fallback quickly Return to return; } // 7, mAddingObserverCounter, and mHandlingEvent are all judgments to determine whether the state is being synchronized. boolean isReentrance = mAddingObserverCounter ! = 0 || mHandlingEvent; State targetState = calculateTargetState(Observer); // echo step 7 to synchronize the code to ++ mAddingObserverCounter++; // If the state of the host is inconsistent with that of the Observer // the state of the Observer passed in will be compared with that of the host. If the state is different, the state of the Observer passed in will be upgraded. // If the host is onResume, the incoming state will go from INITIALIZED to onCreate to onResume. (Here is the first synchronization state, Is the state of the Observer and the state of the host) while (statefulObserver.mState.com pareTo (targetState) < 0 && mObserverMap.contains(observer))) { pushParentState(statefulObserver.mState); final Event event = Event.upFrom(statefulObserver.mState); if (event == null) { throw new IllegalStateException("no event up from " + statefulObserver.mState); } statefulObserver.dispatchEvent(lifecycleOwner, event); popParentState(); // mState / subling may have been changed recalculate targetState = calculateTargetState(observer); } // If (! isReentrance) { // we do sync only on the top level. sync(); } mAddingObserverCounter--; }Copy the code
Synchronize state and distribute state:
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; }Copy the code
The distribution state, either backwardPass () or forwardPass(), ends with:
observer.dispatchEvent(lifecycleOwner, event);
Copy the code
ObserverWithState(LifecycleObserver observer, State initialState) { mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer); mState = initialState; } void dispatchEvent(LifecycleOwner owner, Event event) { State newState = event.getTargetState(); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; }}Copy the code
As mentioned in the previous code, registered observers are encapsulated as ObserverWithState, which is responsible for the distribution of status events.
3.3, How will Lifecycle be implemented?
As you know from the previous section, if your Activity needs to implement an Observer, you need to implement LifcycleOwner. Looking to the roots, you can see ComponentActivity, which implements LifecycleOwner.
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,
{
}
Copy the code
Look directly at the code for onCreate: it has a ReportFragment.
/** * {@inheritDoc} * * If your ComponentActivity is annotated with {@link ContentView}, this will * call {@link #setContentView(int)} for you. */ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { /// ... . ReportFragment.injectIfNeededIn(this); }Copy the code
This LifecycleCallbacks injectIfNeededIn. RegisterIn look and Lifecycle (activity).
public static void injectIfNeededIn(Activity activity) { if (Build.VERSION.SDK_INT >= 29) { // On API 29+, we can register for the correct Lifecycle callbacks directly LifecycleCallbacks.registerIn(activity); } / /... . 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
There is an obvious version determination here, when the SDK is greater than 29
LifecycleCallbacks.registerIn(activity);
Copy the code
When the SDK is less than or equal to 29, it must go:
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
The Fragment lifecycle is the same as initializing a Fragment in an Activity and calling back the Activity lifecycle through the Fragment lifecycle. So you can see this code in ReportFragment. The dispatch() method is very important
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
dispatch(Lifecycle.Event.ON_CREATE);
}
Copy the code
And then we’re going to move to The moveToState method, which we’ll show you in section 2, that this thing is a synchronized state, callback lifecycle method. What happens when SDK >29?
@RequiresApi(29)
static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
static void registerIn(Activity activity) {
activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
}
@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
When the SDK >29, the Activity registers a callback, which is used in the Activity lifecycle, and then calls dispatch to synchronize the state. These states are called back to the Activity.
private void dispatchActivityPostStarted() {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks) callbacks[i])
.onActivityPostStarted(this);
}
}
getApplication().dispatchActivityPostStarted(this);
}
private void dispatchActivityPreResumed() {
getApplication().dispatchActivityPreResumed(this);
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i = 0; i < callbacks.length; i++) {
((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPreResumed(this);
}
}
}
Copy the code
3.4. How will Lifecycle be implemented with fragments
Compared with the implementation of activities, the implementation of fragments is much simpler
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner,
ActivityResultCaller {
}
LifecycleRegistry mLifecycleRegistry;
public Fragment() {
initLifecycle();
}
private void initLifecycle() {
mLifecycleRegistry = new LifecycleRegistry(this);
mSavedStateRegistryController = SavedStateRegistryController.create(this);
}
void performStart() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
void performStop() {
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
Copy the code
There is a LifecycleRegistry member variable, initialized in the Fragment constructor, which then calls the HandleLifecycleEvent on every lifecycle callback, as mentioned earlier, HandleLifecycleEvent calls MoveToState () sync() and distributes the event.
4. Write at the end
So much of the above source code, finally summarize these key points:
- Be sure to understand the specific role of the three key classes LifecycleOwner, Lifecycle, and LifecycleRegistry in this system
- Write a basic Lifecycle
- Activity29 dispatches state via callback above and ReportFragment below.
- Fragment state distribution is directly distributed through lifecycle callbacks.
- Learn about LifecycleRegistry’s registered Observer method, the method for distributing events.