A: concept

Life-cycle-aware components perform operations in response to changes in the life-cycle state of another component, such as an Activity or Fragment. These components help you write more organized and often leaner code that is easier to maintain.

2: usage

1: rely on

Implementation “androidx lifecycle: lifecycle – runtime – KTX: $lifecycle_version” the latest version to 2.3.0

2:

Previously, if a component or method wanted to be associated with an Activity or Fragment lifecycle, it had to be called in each lifecycle using the following method, but this pattern led to poorly organized code and error proliferation.

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

Lifecycle packages provide classes and interfaces for building life-aware components — components that can automatically adjust their behavior based on the current lifecycle state of an Activity or Fragment.

class MyActivity : AppCompatActivity() { private lateinit var myLocationListener: MyLocationListener override fun onCreate(...) { myLocationListener = MyLocationListener(this, lifecycle) { location -> // update UI } Util.checkUserStatus { result -> if (result) { myLocationListener.enable() } } }  } internal class MyLocationListener( private val context: Context, private val lifecycle: Lifecycle, private val callback: (Location) -> Unit ): LifecycleObserver { private var enabled = false @OnLifecycleEvent(Lifecycle.Event.ON_START) fun start() { if (enabled) {  // connect } } fun enable() { enabled = true if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) { // connect if not connected } } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun stop() { // disconnect if connected } }Copy the code

As you can see, MyLocationListener implements the LifecycleObserver interface and then adds the @onlifecycleEvent (Lifecycle.event.on_start) annotation to the corresponding method, which describes the Lifecycle required by the method logic. Then the MyActivity initializes the object, passing in context, lifecycle, and function parameters. Lifecycle is not defined where lifecycle comes from.

Principle 3:

As we all know, if A wants to know the situation of B, but A has no time to watch B himself, it must find A C to watch him, and C will tell A when B changes. This is the observer mode in the program. In the above class MyLocationListener is A, which needs to know about MyActivity, so implementing A LifecycleObserver becomes an observer. MyActivity is the observed. So who is B, who is the notifier, in this case LifeCycle component.

Lifecycle will click into ComponentActivity, which has the following inheritance and implementation classes

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner,
        ViewModelStoreOwner,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner 
Copy the code

Lifecycle is an instance object of LifecycleRegistry.

private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@NonNull
@Override
public Lifecycle getLifecycle() {
   return mLifecycleRegistry;
}
Copy the code

We see ComponentActivity code will find there is ReportFragment in onCreate method. The injectIfNeededIn (this), Click to see that the Fragment is used to listen for the life cycle of ComponentActivity.

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(); }}... @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); }... Omit codeCopy the code

Listen for the activity’s life cycle by creating a layout-free fragment bound to the activity and calling the Dispatch method. Let’s go in and look at the implementation logic of this method

private void dispatch(Lifecycle.Event event) { Activity activity = getActivity(); If (activity instanceof LifecycleRegistryOwner) {// Invalid LifecycleRegistryOwner ((LifecycleRegistryOwner)) activity).getLifecycle().handleLifecycleEvent(event); return; } if (activity instanceof LifecycleOwner) { Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle(); if (lifecycle instanceof LifecycleRegistry) { ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); }}}Copy the code

Can see points to judge, but the first case has expired, so now there is only one case, is LifecycleRegistry. HandleLifecycleEvent (event). The method is to determine what the current life cycle is, and then call sync based on the life cycle

// happens only on the top of stack (never in reentrance), // so it doesn't have to take in account parents 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

Method to determine the call logic by comparing the current life cycle with the life cycle of data in the mObserverMap. The mObserverMap is a collection of maps that holds all the observers, the data sorted by life cycle.

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(); } } } 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(); }}}Copy the code

It turns out that the logic is the same in both methods, calling observer.dispatchEvent. So what is this observer? This observer is an instance object that implements a LifecycleObserver.

Four:

Maybe they still write too little, or not very understand, feel write very dry, next time more practice, more see in writing