Android Jetpack Lifecycles source code analysis

Introduction of Android Jetpack

Jetpack is a set of libraries, tools, and guidelines that make it easier for developers to write great apps. These components help you follow best practices, get you out of boilerplate code, and simplify complex tasks so you can focus on the code you need.

Jetpack contains the Android X.* (Android.*) package library unbundled with the platform API. This means that it provides backward compatibility and updates more frequently than the Android platform, ensuring that you always get the latest and greatest versions of Jetpack components. Introduction to Android Jetpack

Android Jetpack component benefits:

1. Manage the lifecycle of applications (such as background tasks, navigation, and lifecycle management) 2. Build observable data objects to notify View 3 when the underlying database changes. Ui-related data stored in the application rotation that is not destroyed is recovered after the interface is rebuilt 4. Easy implementation of SQLite database 5. The system automatically schedules the execution of background tasks to optimize performance

The use of Lifecycles

2.1 Status transformation diagram

Lifecycles is a class that holds Activity and Fragment information for components that solve lifecycle management problems. By listening to the Handling Lifecycles with Lifecycle-Aware Components and allowing other objects to observe this state. The lifecycle uses two main enumerations to track the lifecycle state of its associated components:

1.Event: Lifecycle events distributed from the framework and Lifecycle classes. These events map to callback events in activities and fragments. 2.State: The current State of the component tracked by Lifecycle object. The mapping between Event and State is shown as follows: The conversion diagram of State on the official website of Android Developer

2.2 Gradle introduces Lifecycles

     def lifecycle_version = "2.0.0"
    // alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
    // AndroidX libraries use this lightweight import for Lifecycle
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
    // For Kotlin use kapt instead of annotationProcessor
    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
    // alternately - if using Java8, use the following instead of lifecycle-compiler
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
Copy the code

2.3 Creating An Observer

1. Create MyCustomLifecycles to inherit LifecycleObserver 2. Use annotations to mark the corresponding lifecycle on each method

Notice the parameters in the defined methods. Lifecycles have requirements for parameters. 1. If the number of parameters is greater than 0. The first parameter must be LifecycleOwner or a superclass 2 of LifecycleOwner. Lifecycle.Event or a superclass of Lifecycle.Event and the annotated Event must be Lifecycle.event.on_any 3. The maximum number of parameters is 2. Otherwise, an illegal status exception occurs

class MyCustomLifecycles() : LifecycleObserver{

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onCreate(lifecycleOwner: LifecycleOwner,event :Lifecycle.Event = Lifecycle.Event.ON_ANY ){
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume(){

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy(){
    }
}

interface MyCallback{
    fun test()}Copy the code

If is to support Java8, and gradle cited * * implementation “androidx. Lifecycle: lifecycle – common – Java8: $lifecycle_version” ` * * can also such a statement

class MyCustomj8Lifecycles : DefaultLifecycleObserver{ override fun onCreate(owner: LifecycleOwner) { super.onCreate(owner) } override fun onResume(owner: LifecycleOwner) {super.onresume (owner)}} /** ** deprecated **/ public class MyGenericLifecycles: GenericLifeCycleObserver { }Copy the code

2.4 Creating observed Activities

class DataBindingActivity : AppCompatActivity(),LifecycleOwner{

}
Copy the code

2.5 create LifecycleRegistry

LifecycleOwner is implemented for SupportActivity in the V4 package. Note that it is under v4 package, not under androidX. The following code

public class SupportActivity extends Activity implements LifecycleOwner, Component {
    private SimpleArrayMap<Class<? extends SupportActivity.ExtraData>, SupportActivity.ExtraData> mExtraDataMap = new SimpleArrayMap();
    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    public SupportActivity() {}}Copy the code

So if your Activity already inherits SupportActivity, SupportActivity is already implemented as LifecycleOwner in the V4 package. You can omit the following code

private lateinit var lifeCycleRegistry: LifecycleRegistry
    private lateinit var myCustomLifecycles: MyCustomLifecycles
    override fun getLifecycle(): Lifecycle {
        return lifeCycleRegistry
    }
Copy the code

2.5 Instantiate MyObserver and bind Lifecycles

The resolution of a custom Observer is involved in the addObserver method.

myCustomLifecycles = MyCustomLifecycles()
lifecycle.addObserver(myCustomLifecycles)
Copy the code

2.7 Setting the markup in the lifecycle

Note: This step can be ignored if your Activity inherits the AppCompatActivity from the V4 package, and observers can still match the observer Event annotation method. But if is androidx appcompat. App. AppCompatActivity, must use markState methods in the lifecycle of the Activity, or annotation methods cannot be enforced. Do not ignore this step. The specific reason will be explained later.

lifeCycleRegistry.markState(Lifecycle.State.CREATED)

lifeCycleRegistry.markState(Lifecycle.State.RESUMED)
Copy the code

The complete class code is as follows:

class DataBindingActivity : AppCompatActivity(),LifecycleOwner{
    private lateinit var lifeCycleRegistry: LifecycleRegistry
    private lateinit var myCustomLifecycles: MyCustomLifecycles
    override fun getLifecycle(): Lifecycle {
        return lifeCycleRegistry
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifeCycleRegistry = LifecycleRegistry(this)

        myCustomLifecycles = MyCustomLifecycles()
        lifecycle.addObserver(myCustomLifecycles)
        lifeCycleRegistry.markState(Lifecycle.State.CREATED)
    }

    override fun onResume() {
        lifeCycleRegistry.markState(Lifecycle.State.RESUMED)
        super.onResume()
    }
}
Copy the code

Source code analysis

We all know Lifecycles are life-cycle sensing activities, so there are a few questions to ask when using Lifecycles: 1. LifecycleObserver declares how annotation methods are triggered when the Activity’s life cycle changes. 2. How the annotation method is executed after the annotation method is triggered. The following with these questions to analyze the source code

3.1 SafeIterableMap analysis

Before analyzing the source code, take a look at the SafeIterableMap class (non-thread-safe), Because the FastSafeIterableMap is used in the class LifecycleRegistry, The parent of FastSafeIterableMap is SafeIterableMap. The SafeIterableMap class is actually a bidirectional linked list that supports key-value pair storage, SupportRemove (interface SupportRemove

{void SupportRemove (@nonnull Entry

Entry); }). This method is recommended when a small amount of data is stored. The SafeIterableMap has the following advantages: 1. The insertion operation of SafeIterableMap is time complexity O(1). Data is directly inserted by pointer movement and no hash algorithm is required. 2. Through the process of removing elements without triggering ConcurrentModifiedException. 3. Using a bidirectional linked list for storage saves memory space compared to a HashMap (Java 8 red-black tree).
,>
,>
,>

  1. Get The GET operation starts from the ab initio pointer (Entry

    mStart) and continues until the Entry corresponding to the key.
    ,>
protected Entry<K, V> get(K k) {
    Entry<K, V> currentNode = mStart;
    while(currentNode ! = null) {if (currentNode.mKey.equals(k)) {
            break;
        }
        currentNode = currentNode.mNext;
    }
    return currentNode;
}
Copy the code
  1. Put Insert the end of the linked list (Entry

    mEnd) and change the positions of mStart and mEnd.
    ,>

protected Entry<K, V> put(@NonNull K key, @NonNull V v) {
    Entry<K, V> newEntry = new Entry<>(key, v);
    mSize++;
    if (mEnd == null) {
        mStart = newEntry;
        mEnd = mStart;
        return newEntry;
    }

    mEnd.mNext = newEntry;
    newEntry.mPrevious = mEnd;
    mEnd = newEntry;
    return newEntry;
}

Copy the code
  1. If the putIfAbsent method does not have a value corresponding to the key, run the PUT method. Otherwise, the data stored before is returned.
public V putIfAbsent(@NonNull K key, @NonNull V v) {
        Entry<K, V> entry = get(key);
        if(entry ! = null) {return entry.mValue;
        }
        put(key, v);
        return null;
    }

Copy the code
  1. The remove method deletes data by moving the pointer to the Next and Previous entry. If data is traversed during the deletion, that is, (! Miterators.isempty ()), which requires the supportRemove method.
public V remove(@NonNull K key) {
        Entry<K, V> toRemove = get(key);
        if (toRemove == null) {
            return null;
        }
        mSize--;
        if(! mIterators.isEmpty()) {for(SupportRemove<K, V> iter : mIterators.keySet()) { iter.supportRemove(toRemove); }}if(toRemove.mPrevious ! = null) { toRemove.mPrevious.mNext = toRemove.mNext; }else {
            mStart = toRemove.mNext;
        }

        if(toRemove.mNext ! = null) { toRemove.mNext.mPrevious = toRemove.mPrevious; }else {
            mEnd = toRemove.mPrevious;
        }

        toRemove.mNext = null;
        toRemove.mPrevious = null;
        return toRemove.mValue;
    }

Copy the code
  1. The supportRemove method is used for traversal deletion. MIterators are weak references to prevent memory leaks caused by objects not being released after traversal. MIterators data is put when performing traversal methods. The mIterators are iterated over when the element is removed (the remove method), removing the data.
private WeakHashMap<SupportRemove<K, V>, Boolean> mIterators = new WeakHashMap<>();

public Iterator<Map.Entry<K, V>> iterator() {
    ListIterator<K, V> iterator = new AscendingIterator<>(mStart, mEnd);
    mIterators.put(iterator, false);
    return iterator;
}

public Iterator<Map.Entry<K, V>> descendingIterator() {
    DescendingIterator<K, V> iterator = new DescendingIterator<>(mEnd, mStart);
    mIterators.put(iterator, false);
    return iterator;
}

public IteratorWithAdditions iteratorWithAdditions() {
    IteratorWithAdditions iterator = new IteratorWithAdditions();
    mIterators.put(iterator, false);
    return iterator;
}

Copy the code

The SupportRemove interface has two implementation classes that call this method to delete an entry whenever an element is deleted and mIterators are not empty. SupportRemove provides safe traversal by adjusting the last pointer to the next element.

IteratorWithAdditions

private class IteratorWithAdditions implements Iterator<Map.Entry<K, V>>, SupportRemove<K, V> {
     
        @Override
        public void supportRemove(@NonNull Entry<K, V> entry) {
        }
    }
Copy the code

ListIterator has two subclasses

private abstract static class ListIterator<K, V> implements Iterator<Map.Entry<K, V>>,
            SupportRemove<K, V> {
        @Override
        public void supportRemove(@NonNull Entry<K, V> entry) {
        }
    }
private static class AscendingIterator<K, V> extends ListIterator<K, V> {
    }

private static class DescendingIterator<K, V> extends ListIterator<K, V> {
   
    }

Copy the code

3.2 Parsing observer: LifecycleObserver

3.2.1 class relationships

Illustrate with a relatively complete diagram on the web, which is designed to the class diagram of the main classes. Lifecycle component members Lifecycle is defined as abstract classes, LifecycleOwner and LifecycleObserver are defined as interfaces. The component implements the LifecycleOwner interface, which has only a method getLifecyle() that returns Lifecycle objects: LifecycleRegistry. Lifecycle’s inner class State indicates the State, and the GenericLifecycleObserver member variable Event represents the Event ObserverWithState inherits from LifecycleObserver The Fragment getLifecycle() method returns LifecycleRegistry that extends from the abstract Lifecycle class.

3.2.2.解析Observer

  1. LifecycleRegistry initializes the control state transition and accepts the distribution of event events. The LifecycleRegistry constructor holds the LifecycleOwner by weak reference. As we know from the above use, the main implementation of the LifecycleOwner is the Activity and Fragment.
 public LifecycleRegistry(@NonNull LifecycleOwner provider) {
        mLifecycleOwner = new WeakReference<>(provider);
        mState = INITIALIZED;
    }
Copy the code
  1. Add an Observer Observer to the component via Lifecycle. AddObserver (myCustomLifecycles)
public void addObserver(@NonNull LifecycleObserver observer) { State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver); . }Copy the code
  1. Generate ObserverWithState, which stores State and GenericLifecycleObserver, and store it in LifecycleObserver, ObserverWithState is stored as a key-value pair in FastSafeIterableMap, which inherits from SafeIterableMap and stores data internally via hashMap.
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); mLifecycleObserver.onStateChanged(owner, event); mState = newState; }}Copy the code
  1. In the constructor of ObserverWithState, GenericLifecycleObserver is created by calling Lifecycling. GetCallback (Observer). Here is returned ReflectiveGenericLifecycleObserver object
 @NonNull
    static GenericLifecycleObserver getCallback(Object object) {
        if (object instanceof FullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
        }
        if (object instanceof GenericLifecycleObserver) {
            return(GenericLifecycleObserver) object; } final Class<? > klass = object.getClass(); inttype = 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

In getCallback, we construct a different GenericLifecycleObserver subclass based on the class we passed in. We know from the context that we passed in a LifecycleObserver subclass, so neither of the following conditions is true.

 if (object instanceof FullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
        }

 if (object instanceof GenericLifecycleObserver) {
            return (GenericLifecycleObserver) object;
        }
Copy the code

S in getObserverConstructorType approach will continue to call resolveObserverCallbackType method, let’s analyze this method. (1) Code block 1: mainly to see if there is a generated XXX_LifecycleAdapter class, XXX represents the custom Observer class. This is not available in version 2.0.0. Probably for compatibility with older code (2) block 2: whether there is an OnLifecycleEvent annotation method. Obviously we do this by way of annotations.

private static int resolveObserverCallbackType(Class<? > klass) {// anonymous class bug:35073837 // Definitely not nullif (klass.getCanonicalName() == null) {
            returnREFLECTIVE_CALLBACK; } // Constructor<? extends GeneratedAdapter> constructor = generatedConstructor(klass);if(constructor ! = null) { sClassToAdapters.put(klass, Collections .<Constructor<? extends GeneratedAdapter>>singletonList(constructor));returnGENERATED_CALLBACK; } / / code block 2 Boolean hasLifecycleMethods = ClassesInfoCache. SInstance. HasLifecycleMethods (klass);if (hasLifecycleMethods) {
            returnREFLECTIVE_CALLBACK; } Class<? > 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));
        }

        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
  1. In the ReflectiveGenericLifecycleObserver constructor, through ClassesInfoCache instance initialization CallbackInfo (singleton).
class ReflectiveGenericLifecycleObserver implements GenericLifecycleObserver {
    private final Object mWrapped;
    private final CallbackInfo mInfo;

    ReflectiveGenericLifecycleObserver(Object wrapped) {
        mWrapped = wrapped;
        mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
    }

    @Override
    public void onStateChanged(LifecycleOwner source, Event event) {
        mInfo.invokeCallbacks(source, event, mWrapped); }}Copy the code
  1. The CallbackInfo and MethodReference classes contain the parameter types and methods of Method
 MethodReference(int callType, Method method) {
            mCallType = callType;
            mMethod = method;
            mMethod.setAccessible(true);
        }
Copy the code

There are basically two HashMaps in CallbackInfo. MEventToHandlers use Event as KeyList as value. The advantage of this storage is that all annotation methods can be found quickly based on events. MHandlerToEvent is stored as a key-value pair of MethodReference and Event, which is an Event corresponding to an annotation method.

 final Map<Lifecycle.Event, List<MethodReference>> mEventToHandlers;
 final Map<MethodReference, Lifecycle.Event> mHandlerToEvent;
Copy the code
  1. The createInfo method retrieves all Observer methods in the getInfo method and stores all Observer method annotations and corresponding Event events in the CallbackInfo HashMap. The previously mentioned limitations on the Observer definition of the annotation method parameters throw an exception in the createInfo method. See the code annotations below for details. (1) Obtain Method and its parameter type, verify the parameter type, and store the parameter type and Method in MethodReference. (2) Call verifyAndPutHandler () to put MethodReference and Lifecycle.Event into the Map. (3) mCallbackMap Map

    stores Observer classes corresponding to CallbackInfo to avoid repeated parsing. MHasLifecycleMethods: this method is used to indicate whether an Observer class has an annotation. Through the analysis of the above seven steps, we have seen how the Observer annotation method is being parsed. In ReflectiveGenericLifecycleObserver onStateChanged method, we assume that if a change in the life cycle, at the time of execution to the corresponding Event affair, executes the method, Get the method in CallbackInfo and call minfo.invokecallbacks (source, event, mWrapped) to execute the corresponding method.
    ,>
 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;
        for (Method method : 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; //1. If the number of parameters is greater than 0. The first parameter must be LifecycleOwner or a superclass of LifecycleOwnerif(! 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 or a superclass of Lifecycle.Event and the annotation //Event must be Lifecycle.eventif(! params[1].isAssignableFrom(Lifecycle.Event.class)) { throw new IllegalArgumentException("invalid parameter type. second arg must be an event");
                }
                if(event ! = Lifecycle.Event.ON_ANY) { throw new IllegalArgumentException("Second arg is supported only for ON_ANY value"); }} //3. The maximum number of parameters is 2. Otherwise, an illegal status exception occursif (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;
    }

Copy the code

3.3 Distribution Process

Above we have analyzed how a custom Observer is parsed, and where the parsed method is triggered. So let’s start with the analysis. First of all, if you inherit a class from a v4 package AppCompatActivity, there is a difference between androidx and v4 package inheritance. The AppCompatActivity superclass has no SupportActivity under AndroidX. Note that it is under v4 package, not under androidX.

  1. SupportActivity we know that the LifecycleOwner interface is implemented in the SupportActivity class. And initializes a ReportFragment in onCrate’s method
@RestrictTo(LIBRARY_GROUP)
public class SupportActivity extends Activity implements LifecycleOwner {
 
 private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); 
 
 @Override
    public Lifecycle getLifecycle() { 
        returnmLifecycleRegistry; } protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ReportFragment.injectIfNeededIn(this); }}Copy the code
  1. ReportFragment (1) Add a ReportFragment instance that uses a small fragment and calls the Dispatch (Event) method during the fragment lifecycle. (2) After calling the handleLifecycleEvent method of LifecycleRegistry with Dispatch (), the process returns to the LifecycleRegistry class. Here we can explain a question: The SupportActivity in the V4 package will execute the handleLifecycleEvent and trigger the Event Event due to the presence of the ReportFragment, while the SupportActivity in the AndroidX package does not have the ReportFragment inheritance. So we can’t sense life cycle changes, we need to be in the Activity’s life cycle for markState to work, so here we guess: Using the LifeEvent method to mark events in an Observer, when the Activity state changes (actually triggered by a ReportFragment), the system determines which state it is about to change to. According to the two states for sure to perform before and after the Event Then execute ReflectiveGenericLifecycleObserver onStateChanged methods, according to the above method of parsing out execution logic
public class ReportFragment extends Fragment {
    private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle"
            + ".LifecycleDispatcher.report_fragment_tag"; Public static void injectIfNeededIn Activity (Activity) {/ / initializes the fragments. Android app. FragmentManager manager = activity.getFragmentManager();if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            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);
    }
 
    @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);
        mProcessListener = null;
    }
 
    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) { ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); }}}}Copy the code
  1. HandleLifecycleEvent () obtains the next state according to the Event in the handleLifecycleEvent method, which is converted to 3.2.1. The Event is then executed based on the next state. MarkState executes the process and handleLifecycleEvent almost always, minus the getStateAfter method.
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);
    }
Copy the code
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; / / code 1if(mHandlingEvent || mAddingObserverCounter ! = 0) { mNewEventOccurred =true;
            // we will figure out what to do on upper level.
            return;
        }
        mHandlingEvent = true;
        sync();
        mHandlingEvent = false;
    }
Copy the code

Note at code 1: mHandlingEvent = true while changing state in sync; MAddingObserverCounter when we call addObserver! = 0 the above two states are the state of the task being executed. Therefore, directly return in getStateAfter will determine the next state to be reached after the execution of the Event according to the execution of the Lifecycle.Event. Then modify the activity lifecycle using sync() in moveToState () : 4. Sync (), as the name suggests, is used to synchronize events. (1) Check whether there is a LifecycleOwner object. LifecycleOwner is initialized by reference in the constructor. 2) We know that Lifecycle.Event and Lifecycle.State will be declared in the same order as the declaration cycle of the activity. Eldest () gets the first data in the bimodal list, while mobServermap.newest () gets the tail data, so the advantage of this data structure is that it can get the header and tail Pointers directly. For example, the life cycle of the activity is CREATED (the state saved in mObserverMap is CREATED), and the state of the next transformation is Started(mState is Started). From the declaration cycle, we can know when onStart () is executed. The corresponding LIfecycle.Event is onStart.


private void sync() {
        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;
            // 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
  1. ForwardPass method

The reason for the while loop is that multiple observers exist. In the forwardPass () method, the State saved in ObserverWithState is compared to mState, if less than the target State. UpEvent () is then called to find the Event to execute based on the saved state, and the Observer’s dispatEvent () method is called to send the Event.

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
    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);
    }
Copy the code
  1. DispatchEvent method by the above analysis the Observer, the mLifecycleObserver is ReflectiveGenericLifecycleObserver object. So you will perform to the ReflectiveGenericLifecycleObserver onStateChanged method. This corresponds to our analysis above.
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); mLifecycleObserver.onStateChanged(owner, event); mState = newState; }}Copy the code
  1. Real method execution (1) invokeCallbacks fetch MethodReference through mEventToHandlers and (2) invokeMethodsForEvent executes MethodReference backwards Invoke invoke based on the parameter type. CALL_TYPE is initialized when parsing the Observer
 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);
                }
            
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 new RuntimeException(e); }}Copy the code
  1. Logout Observer executes the remove method of LifecycleRegistry directly.
@Override
    public void removeObserver(@NonNull LifecycleObserver observer) {
        // we consciously decided not to send destruction events here in opposition to addObserver.
        // Our reasons for that:
        // 1. These events haven't yet happened at all. In contrast to events in addObservers, that // actually occurred but earlier. // 2. There are cases when removeObserver happens as a consequence of some kind of fatal // event. If removeObserver method sends destruction events, then a clean up routine becomes // more cumbersome. More specific example of that is: your LifecycleObserver listens for // a web connection, in the usual routine in OnStop method you report to a server that a // session has just ended and you close the connection. Now let's assume now that you
        // lost an internet and as a result you removed this observer. If you get destruction
        // events in removeObserver, you should have a special case in your onStop method that
        // checks if your web connection died and you shouldn't try to report anything to a server. mObserverMap.remove(observer); }Copy the code