Lifecycle aware components that execute, manipulate, and respond to changes in the Lifecycle state of another component such as an Activity or Fragment.

Lifecycle version of this article is 2.2.0:

Implementation ‘androidx. Lifecycler: lifecycle – common: 2.2.0’ / / 22.2.23 update 2.5, version 2.2 is used more

Do you truly understand Lifecycle?

Lifecycle is very, very simple to use. By default you will have used Lifecycle. But if I ask you the following questions. How many can you answer?

  • LifecycleHow many ways can you create?
    • What’s the difference? Which one is recommended? Why is that?
  • EventEvents andStateWhat is the relationship between states
    • onStop()Life cycle, in whatStatestate
  • LifecycleHow is life cycle synchronization done
    • If theonResume()registeredThe observerWhat kinds of callbacks do you receive? Why is that?
  • Activity/FragmentWill Lifecycle capabilities be implemented in the same way?
    • Why do they do that? What are the benefits?
    • Does the Application sense the Activity lifecycle? (How Lifecycle can be used to listen on the front and back)
  • LifecycleFrom the source point of view, brieflyLifecycleRegistration, distribution, perception process
  • whatNested event? When did it happen?LifecycleHow is it solved?

If I was an interviewer and there was a CV that said I knew the Jetpack component I would ask Lifecycle these questions. Because it is first and foremost the cornerstone of the implementation capabilities of Jetpack’s other two super core components, ViewModel,LiveData. It is also used very frequently. It seems simple and easy to ignore, but there is a lot to learn from it.

These dozen questions, from usage to source, from surface to extension. If you know everything Lifecycle is 80% Lifecycle. Yes. It’s only 80%. Because of the source code analysis below, there are more extended problems.

Lifecycle

As a lifecycle aware component, its role is to listen for the host Activity/Fragment and send it to the observer. This seemingly simple generalization reveals three important roles: host, observer, and scheduler for distribution

Lifecycle is simple:

  1. Create an Observer that directly inherits its parent class:LifecycleObserver
public class LocationObserver implements LifecycleObserver {
    private static final String TAG = "LocationObserver";
    //1. Custom LifecycleObserver that uses annotations to declare the state of the host observed by each method
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreate(@NotNull LifecycleOwner owner) {
        Timber.e("onCreate_ON_CREATE");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart(@NotNull LifecycleOwner owner) {
        Timber.e("onStart_ON_START");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume(@NotNull LifecycleOwner owner) {
        Timber.e("onResume_ON_RESUME");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void onPause(@NotNull LifecycleOwner owner) {
        Timber.e("onPause_ON_PAUSE");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop(@NotNull LifecycleOwner owner) {
        Timber.e("onStop_ON_STOP");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestroy(@NotNull LifecycleOwner owner) {
        Timber.e("onDestroy_ON_DESTROY");
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    void onAny(LifecycleOwner owner) {
        Timber.e("onAny_ON_ANY-->%s", owner.getLifecycle().getCurrentState()); }}Copy the code

Define your own lifecycle methods and annotate each method with the corresponding lifecycle annotations. You can also get a LifecycleOwner, which is the host Activity

  1. Inheritance:LifecycleEventObserver, copyingonStateChangedMethods:
public class EventObserver implements LifecycleEventObserver {

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
        switch (event) {
            case ON_CREATE:
                Timber.d("ON_CREATE");
                break;
            case ON_START:
                Timber.d("ON_START");
                break;
            case ON_RESUME:
                Timber.d("ON_RESUME");
                break;
            case ON_PAUSE:
                Timber.d("ON_PAUSE");
                break;
            case ON_STOP:
                Timber.d("ON_STOP");
                break;
            case ON_DESTROY:
                Timber.d("ON_DESTROY");
                break;
            default:
                break; }}}Copy the code
  1. Inheritance:FullLifecycleObserver, directly overwrite the corresponding lifecycle callback:
public class FullLocationObserver implements DefaultLifecycleObserver {
    @Override
    public void onCreate(@NonNull LifecycleOwner owner) {
        Timber.e("onCreate");
    }
    @Override
    public void onStart(@NonNull LifecycleOwner owner) {
        Timber.e("onStart");
    }
    @Override
    public void onResume(@NonNull LifecycleOwner owner) {
        Timber.e("onResume");
    }
    @Override
    public void onPause(@NonNull LifecycleOwner owner) {
        Timber.e("onPause");
    }
    @Override
    public void onStop(@NonNull LifecycleOwner owner) {
        Timber.e("onStop");
    }
    @Override
    public void onDestroy(@NonNull LifecycleOwner owner) {
        Timber.e("onDestroy"); }}Copy the code

At this point you’ll notice that you can’t inherit the FullLifecycleObserver directly and you’ll need to add a dependency:

Implementation ‘androidx. Lifecycler: lifecycle – common: 2.2.0’ replace rely on the introduction of the above (default will integrate the above) implementation “Androidx. Lifecycle: lifecycle – common – java8:2.2.0.” “

Inheritance: DefaultLifecycleObserver, which is a subclass of FullLifecycleObserver because after Java8, the interface interface type is supported and can have its own default implementation.

Then call the following method in Activity#OnCreate() :

     lifecycle.addObserver(LocationObserver())
Copy the code

Lifecycle will then be available to Lifecycle.

Learn the process from the source code

If you are MVP, you can have your Presenter implement an Observer to gain awareness while working with logic. But what happens if we put the registered code lifecycle.addobServer (LocationObserver()) into the onResume() method? You will notice that the Observer can receive onCreate,onStart as well as onResume events. In other words, the state of the host is synchronized to the observer. How is this done?


The perception listens for getLifecycle and goes into the ComponentActivity core code:

public class ComponentActivity extends Activity implements LifecycleOwner{
  private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
   @NonNull
   @Override
   public Lifecycle getLifecycle(a) {
      return mLifecycleRegistry;
   }
  
  protected void onCreate(Bundle bundle) {
      super.onCreate(savedInstanceState);
      // Add a fragment to the Activity to report life cycle changes
      // The purpose is to accommodate scenarios that do not inherit from AppCompactActivity.
      ReportFragment.injectIfNeededIn(this); 
}

Copy the code
  1. LifecycleRegistry isLifecycle A subclass ofnew LifecycleRegistry(this);theThe host's Owner, that is, the presentActivityPass it in as a construct parameter
  2. ActivityIt’s not just handing out lifecycles, it’s using them ReportFragment.injectIfNeededIn(this).
public class ReportFragment extends Fragment{
  public static void injectIfNeededIn(Activity activity) {
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(newReportFragment(), REPORT_FRAGMENT_TAG).commit(); manager.executePendingTransactions(); }}@Override
    public void onStart(a) {
        super.onStart();
        dispatch(Lifecycle.Event.ON_START);
    }
    @Override
    public void onResume(a) {
        super.onResume();
        dispatch(Lifecycle.Event.ON_RESUME);
    }
    @Override
    public void onPause(a) {
        super.onPause();
        dispatch(Lifecycle.Event.ON_PAUSE);
    }
    @Override
    public void onDestroy(a) {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
    }
    private void dispatch(Lifecycle.Event event) {
         Call the host's Lifecycle
         Lifecycle lifecycle = activity.getLifecycle();
         if (lifecycle instanceofLifecycleRegistry) { ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); }}Copy the code

ReportFragment. InjectIfNeededIn (this) is used in the Activity, creating an invisible fragments. When the Fragment’s lifecycle changes, events are distributed via dispatch() followed by a call ((LifecycleRegistry) lifecycle).handlelifecycleevent (event). The idea is that when a page inherits ComponentActivity directly, instead of inheriting ComponentActivity, it loses the ability to be aware. You need to implement LifecycleOwner yourself, override getLifecycle(), and then pass yourself into new LifecycleRegistry(this) to become the host for other observers to listen on. ReportFragment. InjectIfNeededIn (this) another use local LifecycleDispatcher:

class LifecycleDispatcher {

    private static AtomicBoolean sInitialized = new AtomicBoolean(false);

    static void init(Context context) {
        if (sInitialized.getAndSet(true)) {
            return;
        }
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
    }

    @SuppressWarnings("WeakerAccess")
    @VisibleForTesting
    static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {

        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            ReportFragment.injectIfNeededIn(activity);
        }

        @Override
        public void onActivityStopped(Activity activity) {}@Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}}private LifecycleDispatcher(a) {
  
Copy the code

Inject ReportFragment directly into the Activity so that each page can be hosted by the observer. Of course, You’ll implement LifecycleOwner yourself, override getLifecycle(), and then pass yourself into new LifecycleRegistry(this). == This part has little to do with Lifecycle and is simply an extension of knowledge ==

Conclusion:

  1. The listening process is,Activity/FragmentinheritanceLifecycleOwnerAnd in subclassesCommponentActivityCreated in theLifecycleA subclass ofLifecycleRegistry. In facsimilegetLifecycle()Will subclass the methods ofLifecycleRegistryTo return.
  2. inonCreate()In theInjection ReportFragment, after the lifecycle callback, passesgetLifecycle()Is obtained by the method ofLifecycleRegistryThe object of thehandleLifecycleEvent(event)Method sends life cycle events to each observer.

The reason for using Activity as an example, rather than Fragement as in other articles, is that if you look at the source code, you’ll see that the Dispatch () process in the ReportFragment class is exactly the same as Fragement:

public class Fragment implements xxx.LifecycleOwner {
    / /...
    void performCreate(Bundle savedInstanceState) {
        onCreate(savedInstanceState);  //1. Execute the lifecycle method first
        / /... Omit code
        //2. Lifecycle event distribution
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }

    void performStart(a) {
        onStart();
        / /...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }

    void performResume(a) {
         onResume();
        / /...
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }

    void performPause(a) {
        //3. Note that the order of calls has changed
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
        / /...
        onPause();
    }

    void performStop(a) {
       mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
        / /...
        onStop();
    }

    void performDestroy(a) {
        mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        / /...onDestroy(); }}Copy the code

With reference toLifecycle, @ShymanZhuSequence diagram of the paper:

PerformCreate (), performStart(), and performResume() will call their own onXXX() methods. LifecycleRegistry then calls the handleLifecycleEvent() method; In performPause(), performStop(), and performDestroy(), LifecycleRegistry’s handleLifecycleEvent() method is first invoked and its own onXXX() method is then called. Excerpted from -Lifecycle: Lifecycle components in detail & analysis of principles


Synchronization above is the listening process, getLifecycle().addobServer (LocationObserver()) registers the first half of the code. Now we have the ability to sense the host and forward the event to LifecycleRegistry, which is at the heart of the process. Now come to the second half, how you can register an Observer and feel the full life cycle at any time (except onDestory).

But before we do that, what are states and events

public abstract class Lifecycle {
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);
     @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);
    @MainThread
    @NonNull
    public abstract State getCurrentState(a);   
    
public enum Event {
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_ANY
    }
public enum State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        /**
         *     <li>after {@link android.app.Activity#onStart() onStart} call;
         *     <li><b>right before</b> {@linkandroid.app.. Activity#onPause( onPause} call. * </ul> */
        STARTED,
        RESUMED;
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0; }}}Copy the code

Lifecycle has two enumerations in addition to add and remove. Event corresponds to onCreate and onStart() of Activty. There are only five states. Take the STARTED state for example: this state occurs after Activity#onStart() and before Activity#onPause(). What does that mean? Take a look at the chart below:

I’m sure we’ve seen this before, but this time we’re in halfCut a knife, indicated aboveLife cycle progression, as shown belowRegression of the life cycle, be sure to remember that this is after our understanding of the source codeIt is very important, and then we explain:

When the Activity is CREATED, it must be INITIALIZED, and when the onCreate() method is executed, it enters the CREATED state.

After the onStart() method, you go to the STARTED state, and after the onResume() method, you go to the RESUMED state.

After moving to the next Activity, execute onPase() and return to the STARTED state, execute onStop() and create state, and execute onDestory() and DESTROYED state. This process represents a regression of the life cycle

With reference toLifecycle, @ShymanZhuDiagram of the paper:

For reference only, the relationship in the ObserverWithState class has changed, mLifeCycleObserver->LifeCycleEventObserver

LifecycleRegistryshi lifecycle where events are registered, logged, and distributed. Understanding the relationship between states and events is very helpful for understanding LifecycleRegistry. Here is an example of a call to lifecycle.addobServer (LocationObserver()) in onResume() :


    public LifecycleRegistry(@NonNull LifecycleOwner provider) {
        mLifecycleOwner = new WeakReference<>(provider);
        mState = INITIALIZED;
    }

    public void addObserver(@NonNull LifecycleObserver observer) {
        / / 1
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        / / 2
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        / / 3
        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;
        }

        booleanisReentrance = mAddingObserverCounter ! =0 || mHandlingEvent;
        / / 4
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            / / 5
            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--;
    }
    // Does not inherit from 'Observer'
    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; }}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);
    }
    
    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;
                // Something in the life cycle happens. You are at the end of the RESUMED phase and can't go any further. Because then there's a life cycle regression
                // So an exception is thrown
            case RESUMED:
                throw new IllegalArgumentException();
        }
        throw new IllegalArgumentException("Unexpected state value " + state);
    }
    // Determine the state according to the event
    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
  1. mStatesaidhostthestateorObserverShould be in the right state, if notDESTROYED , then the value is assigned toINITIALIZEDState, what do you mean? That’s when you add oneObserverThe timing is inonDestory()So just set it toDESTROYED , and then do not send events to the observer, otherwise even if you are inonReume()Registration, bothINITIALIZED, why do it instead of just giving it awayRESUMED. This is theLifecycleRegistryBecause he’s going to do it nextThe event.If it is distributed directlyRESUMEDThe observer is not lostON_CREATE.ON_STARTEvent? This has to do withLifecycycleThe original intention of the design is definitely not consistent
  2. willobserverandinitialStateAnd encapsulated intoObserverWithStateFrom the class name, it can be seen that he is holdingThe observerAnd itThe current statePackaging class,.
  3. The observerObserverAs the key,ObserverWithStateEncapsulate Value into Map,mObserverMapThere’s not much to say about this store, but it has a very special data structure, you can think of it as a Map of linked list structures, which records the Start and End of the chain, and each Value element, which records the Next and Previous of the current Value.
  4. calculateTargetStateCalculate the destination state, i.e. calculate the incoming stateObserverWhat the state should be. And the logic of computation is very interesting. The expansion theory involvesNested eventNow, let’s do it again, just in terms of the previous one in the setObserverState andhostState and currentObserverShould be in the right statemStateAs amin()Comparison. From this we can conclude:An Activity/Fragment can have multiple observers, each with the same state
  5. Loop judgment, if the observer state is less than the target stateLife cycle progression occurs. call upEvent(State state)Compute forward events. Initialization isINITIALIZEDState, where a forward event occurs, should occur according to the previous diagramON_CREATEEvents. It’s kind of hard to understand. isLess thanIn the case of. Life cycle progression is definitely happening, soINITIALIZEDIn state, the next event must beON_CREATEEvents. And then callObserverWithState #dispatchEvent()Through thegetStateAfter(event)To determine the state of affairs based on events.ON_CREATEThe event must beCREATEDState. And then save itnewStateInvokes the callback method of the registered observermLifecycleObserver.onStateChanged(owner, event)Distribute the event and update the mStatemState = newState.

UpEvent ():CREATED–>ON_START,getStateAfter(event) : ON_START–>STARTED, save the state newState, the callback listens on onStateChanged, save the state: mState = newState until mState = RESUMED

After the cycle. The new registrationObserverAnd the hostsynchronousTo the same life cycle.

distributed When the host life cycle changes, will call mLifecycleRegistry. HandleLifecycleEvent (Lifecycle. Event. ON_RESUME); Distribute it to observers, look at the analysis directly and then combine the source code

    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);/ / 1
    }

    private void moveToState(State next) {
        mState = next;
        sync();/ / 2
    }
    
    private void sync(a) {
        while(! isSynced()) {/ / 3
        If the host State is smaller than the earliest added observer, why the earliest, the first set of observers are added in order, the State should be consistent, smaller than the earliest observer, must be smaller than the last observer
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                backwardPass(lifecycleOwner);/ / 4
            }
            Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
            if(! mNewEventOccurred && newest ! =null
                    // The same is true when the host state is greater than the latest
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);/ / 5}}}private boolean isSynced(a) {
        if (mObserverMap.size() == 0) {
            return true;
        }
        State eldestObserverState = mObserverMap.eldest().getValue().mState;
        State newestObserverState = mObserverMap.newest().getValue().mState;
        return eldestObserverState == newestObserverState && mState == newestObserverState;
    }
    
    private void backwardPass(LifecycleOwner lifecycleOwner) {
            while ((observer.mState.compareTo(mState) > 0&&! mNewEventOccurred && mObserverMap.contains(entry.getKey()))) { Event event = downEvent(observer.mState); observer.dispatchEvent(lifecycleOwner, event); }}private void forwardPass(LifecycleOwner lifecycleOwner) {
            while ((observer.mState.compareTo(mState) < 0&&! mNewEventOccurred && mObserverMap.contains(entry.getKey()))) { observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState)); }}private static Event downEvent(State state) {
        switch (state) {
        // The initial state cannot be retraced
            case INITIALIZED:
                throw new IllegalArgumentException();
            case CREATED:
                return ON_DESTROY;
            case STARTED:
                return ON_STOP;
            case RESUMED:
                return ON_PAUSE;
                // The last state cannot be reversed
            case DESTROYED:
                throw new IllegalArgumentException();
        }
        throw new IllegalArgumentException("Unexpected state value " + state);
    } 
Copy the code
  1. Based on incoming eventsevent, determine the state of the host
  2. replicatemState = nextAnd then callsync()Start synchronizationAll observers
  3. isSynced()If it’s already synchronized, take out the elements in the Map, the first and last elements are equal and add the last element, the latest element and the host statemStateIf it is the same, it means that synchronization is not necessary. Again:An Activity/Fragment can have multiple observers, each with the same stateBut pay attention tosync()Is taken innonwhile (! isSynced())So inconsistencies enter the next loop
  4. if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0), host stateLess thanThe observer state, what’s going on here? If you read the previous table, it’s not hard to understand here, for example: The observer isRESUMEDState when the host occursonPase()Life cycle, sohostWill enterSTARTEDState. Enter theLife cycle regressionProcedure. So it callsbackwardPass(lifecycleOwner)Pass backwards.
  5. (observer.mState.compareTo(mState) > 0It’s the hostLess thanThe observer,backwardPassJudge observerIs greater thanHost, which means exactly the same thing, is then calleddownEventIs rolled back based on the statusRESUMED–>ON_PAUSE
  6. observer.dispatchEvent(lifecycleOwner, event)Update status, distributeThe observerEvents, updatesmState
  7. mState.compareTo(newest.getValue().mState) > 0Events forwardforwardPass(lifecycleOwner);And beforesynchronousExactly the same process

Unified the Observer

Consider a question: ObserverWithState#dispatch is a location that distributes events to observers, but it calls onStateChange(), but our callback implementation is completely different. How can it be unified?

    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

MLifecycleObserver = Lifecycling. LifecycleEventObserver (observer) the answer is the adapter pattern, see here:

    @NonNull
    static LifecycleEventObserver lifecycleEventObserver(Object object) {//Object is the passed observer
        boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
        boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
        if (isLifecycleEventObserver && isFullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
                    (LifecycleEventObserver) object);
        }
        if (isFullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
        }

        if (isLifecycleEventObserver) {
            return (LifecycleEventObserver) object;
        }

        finalClass<? > klass = object.getClass();// Key code
        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);
        }
        return new ReflectiveGenericLifecycleObserver(object);
    }
Copy the code
  • Object is passed inobserverIf yes if simultaneously implementedLifecycleEventObserver.FullLifecycleObserverTo createFullLifecycleObserverAdapter
  • If it isisFullLifecycleObserverTo createFullLifecycleObserverAdapter
  • If it isisLifecycleEventObserver, return directly

While FullLifecycleObserverAdapter FullLifecycleObserverAdapter, all Adapter Adapter is inherited from LifecycleEventObserver so you can curl call after unification

How does a LifecycleObserver inherit directly? :

inttype = getObserverConstructorType(klass); The final call/** * Create a name for an adapter class. */
    public static String getAdapterName(String className) {
        return className.replace("."."_") + "_LifecycleAdapter";
    }
Copy the code

When introducing androidx. Lifecycle: lifecycle – compiler: 2.2.0 will use APT, runtime annotation processor to generate tools and splicing class name: MyObserver_LifecycleAdapter, then obtaining annotations mark observer, whether the person will use ReflectiveGenericLifecycleObserver, reflection is carried out.

Nested event

This part is not easy to understand. At present, my personal understanding is to first make clear: when will the nested event occur? There are two cases:

  1. Synchronization is not yet complete when a new observer is addedhostA life cycle change occurs again, which then leads to out-of-sync problems
  2. In the distributedThe life cycleWhen a new observer is added to an observer, the new observer may be out of sync with other observers.

Nested events are, in plain English, synchronization conflicts. Because the states of all observers and hosts are exactly the same, once the lifecycle is dispatched, or when new observers are added, changes in the lifecycle or observer set elements can result in unsynchronization. This confusion does not come from multithreading. Because careful you will find. Most of LifeCycleRegistry’s methods are annotated with the @MainThread annotation. In other words, the conflict is not with multithreading, but with the two cases above.

So how does LifeCycleRegistry work? The answer is to use multiple marker bits to represent the state while pushing the newly added or changing observers onto the stack. After proper synchronization, the stack is removed, that is, mParentStates, a collection of type mParentStates. Therefore, once the observer state is inconsistent, it cannot be removed from the stack normally. The elements in mParentStates are not empty. It needs to be reprocessed or judged. The idea is something like this. Multiple tag bits and stack management to ensure state synchronization and consistency. Above is personal understanding. LifeCycle will handle nested events if LifeCycle is interested in understanding them further

Conclusion:

LifeCycle components are simple, in-depth yet complex and interesting to understand. But most essays fail to be both in-depth and reflective of other people’s differences. I can’t answer the first dozen questions completely. But by now you should have your own answer.