Detailed analysis of Lifecycle

Keywords: Fragment network github Android

Lifecycle source code analysis

Catalogue introduction

  • 01. What is the role of lifecycle
  • 02. Simple use of lifecycle
  • 03. Usage scenarios of lifecycle
  • 04. How to realize life cycle awareness
  • 05. How annotation methods are called
  • 06.addObserver call analysis
  • 07. Sort out and summarize the knowledge points

00. Using AAC to realize bus event bus

  • Using LiveData to realize event bus instead of EventBus. By making full use of the life cycle awareness function, these components can be updated when the activities, fragments, or services life cycle is active. It supports sending common events, sticky events, delay messages, rotation training delay messages, etc.
  • https://github.com/yangchong211/YCLiveDataBus

01. What is the role of lifecycle

  • Lifecycle is a library specially used to process the life cycle. It can help us to completely decouple the life cycle processing of Activity and Fragment from the business logic processing, so that we can focus on the business more, and make the code of Activity and Fragment more readable and maintainable through decouple.

02. Simple use of lifecycle

  • Take a look at the following case. The usage is very simple. The code is as follows
    • You can get the Lifecycle through the getLifecycle() method and add Observer to monitor the Activity Lifecycle.
    public class FourActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            BusLogUtils.d("------AppCompatActivity onCreate() called");
            testLifecycle();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            BusLogUtils.d("------AppCompatActivity onResume() called");
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            BusLogUtils.d("------AppCompatActivity onDestroy() called");
        }
    
        private void testLifecycle() {
            getLifecycle().addObserver(new LifecycleObserver() {
    
                @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
                void onCreate(){
                    BusLogUtils.d("------LifecycleObserver onCreate() called");
                }
    
                @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
                void onResume(){
                    BusLogUtils.d("------LifecycleObserver onResume() called");
                }
                
                @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
                void onDestroy(){
                    BusLogUtils.d("------LifecycleObserver onDestroy() called");
                }
            });
        }
    }
    
  • Then print the log as follows
    • It can be found that Lifecycle can listen to the life cycle of activity.
    • When the activity is created, the onCreate method of the life cycle in the activity takes precedence over the onCreate method in the lifecycle observer. When the activity is closed, the reverse happens!
    //Open page
    2020-03-06 09:44:09.522 11647-11647/com.ycbjie.yclivedatabus D/BusLogUtils: ------AppCompatActivity onCreate() called
    2020-03-06 09:44:09.545 11647-11647/com.ycbjie.yclivedatabus D/BusLogUtils: ------LifecycleObserver onCreate() called
    2020-03-06 09:44:09.551 11647-11647/com.ycbjie.yclivedatabus D/BusLogUtils: ------AppCompatActivity onResume() called
    2020-03-06 09:44:09.552 11647-11647/com.ycbjie.yclivedatabus D/BusLogUtils: ------LifecycleObserver onResume() called
    
    //Close page
    2020-03-06 09:44:14.265 11647-11647/com.ycbjie.yclivedatabus D/BusLogUtils: ------LifecycleObserver onStop() called
    2020-03-06 09:44:14.265 11647-11647/com.ycbjie.yclivedatabus D/BusLogUtils: ------AppCompatActivity onStop() called
    2020-03-06 09:44:14.266 11647-11647/com.ycbjie.yclivedatabus D/BusLogUtils: ------LifecycleObserver onDestroy() called
    2020-03-06 09:44:14.266 11647-11647/com.ycbjie.yclivedatabus D/BusLogUtils: ------AppCompatActivity onDestroy() called
    

03. Usage scenarios of lifecycle

  • The application scenarios of Lifecycle are very extensive. We can use the mechanism of Lifecycle to help us separate all the business logic related to Lifecycle and decouple it completely.
    • For example, video pause and play,
    • Message removal of Handler,
    • Cancellation of network request,
    • Attach & detach view of Presenter
    • Pause and resume animation
    • And it can be implemented in a more elegant way, and we have a cleaner and readable activity & fragment.
  • Cancellation of network request
  • Stop and turn on video buffering
    • Start video buffering as soon as possible with life-cycle enabled components, but delay playback until the application is fully started. You can also use lifecycle aware components to terminate the buffer when the application is destroyed.
  • Start and stop network connections
    • Using life cycle aware components, you can update (stream) network data in real time when the application is in the foreground state, and automatically pause when the application enters the background.
  • Pause and resume animation
    • When the application is running in the background, use the life cycle awareness component to process the pause animation drawing, and resume the drawing after the application is running in the foreground.

04. How to realize life cycle awareness

  • Looking at the above simple case, you can see that the annotation @ onlife event (lifecycle. Event. On? Create) annotation method is used, which can not only perform life cycle monitoring.
  • Then trace to the Lifecycle.Event class and see where the annotation is used. The screenshot is shown below. Here we will first look at the ReportFragment class, which seems to have something to do with Fragment!

4.1 life cycle events and states

  • Annotation is used in the above case, so what state does it have?
    • Lifecycle is an abstract class, which has two main functions: one is the Event lifecycle, the other is the State state.
    • Lifecycle.Event represents the state of a lifecycle, similar to an Activity lifecycle.
    • Lifecycle.State represents the lifecycle state of the current component,
    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();
    
        @SuppressWarnings("WeakerAccess")
        public enum Event {
            ON_CREATE,
            ON_START,
            ON_RESUME,
            ON_PAUSE,
            ON_STOP,
            ON_DESTROY,
            ON_ANY
        }
        @SuppressWarnings("WeakerAccess")
        public enum State {
            DESTROYED,
            INITIALIZED,
            CREATED,
            STARTED,
            RESUMED;
            public boolean isAtLeast(@NonNull State state) {
                return compareTo(state) >= 0;
            }
        }
    }
    
  • Relationship between Event and State (from network)

4.2 analysis of reportfragment class

  • The source code is as follows, only part of the source code related to the life cycle is extracted here.
    • By rewriting the life cycle callback method, you can see that dispatch(Lifecycle.Event.XXX) is invoked in the lifecycle method, and this ReportFragment is playing a role.
    • Lifecycle uses Fragment to realize listening life cycle, and finally uses dispatch to distribute life cycle events.
    • When the Fragment life cycle changes, the dispatch method is called to distribute the life cycle, in which the handlelifcycleevent method of LifecycleRegistry is called.
    public class ReportFragment extends Fragment {
    
        //This method is very important. Search those places and use this method
        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) {
                //Add Fragment to Activity
                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);
            //Distribution state
            dispatch(Lifecycle.Event.ON_CREATE);
        }
    
        @Override
        public void onStart() {
            super.onStart();
            dispatchStart(mProcessListener);
            //Distribution state
            dispatch(Lifecycle.Event.ON_START);
        }
    
        @Override
        public void onResume() {
            super.onResume();
            dispatchResume(mProcessListener);
            //Distribution state
            dispatch(Lifecycle.Event.ON_RESUME);
        }
    
        @Override
        public void onPause() {
            super.onPause();
            //Distribution state
            dispatch(Lifecycle.Event.ON_PAUSE);
        }
    
        @Override
        public void onStop() {
            //Distribution state
            super.onStop();
            dispatch(Lifecycle.Event.ON_STOP);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            //Distribution state
            dispatch(Lifecycle.Event.ON_DESTROY);
            // just want to be sure that we won't leak reference to an activity
            mProcessListener = null;
        }
        
        //Distribute lifecycle events
        private void dispatch(Lifecycle.Event event) {
            // Get host activity
            Activity activity = getActivity();
            if (activity instanceof LifecycleRegistryOwner) {
                //The source code of handlelife cycleevent method is analyzed later
                ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
                return;
            }
    
            if (activity instanceof LifecycleOwner) {
                Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
                if (lifecycle instanceof LifecycleRegistry) {
                    ////The source code of handlelife cycleevent method is analyzed later
                    ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
                }
            }
        }
       //...
    }
    
  • Then let's see where the ReportFragment class is used. Trace it to the onActivityCreated method in the dispatcher activitycallback internal class in the lifecycle dispatcher. The source code is as follows
    class LifecycleDispatcher {
    
        static void init(Context context) {
            if (sInitialized.getAndSet(true)) {
                return;
            }
            ((Application) context.getApplicationContext())
                    .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
        }
    
        @SuppressWarnings("WeakerAccess")
        @VisibleForTesting
        static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
            private final FragmentCallback mFragmentCallback;
    
            DispatcherActivityCallback() {
                mFragmentCallback = new FragmentCallback();
            }
    
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                if (activity instanceof FragmentActivity) {
                    ((FragmentActivity) activity).getSupportFragmentManager()
                            .registerFragmentLifecycleCallbacks(mFragmentCallback, true);
                }
                ReportFragment.injectIfNeededIn(activity);
            }
        }
    }
    
  • Next, take a look at the handlelife cycleevent (Event) source code. You can find that the State is obtained according to the Event State, and then the State is distributed. In the future, we will analyze
    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);
    }
    

4.3 ComponentActivity class analysis

  • fragment needs to depend on the host activity. By searching the call place of ReportFragment.injectIfNeededIn, we found that ComponentActivity called this method. (the version below API 28 is SupportActivity)
    • A LifecycleRegistry member object is created internally, and the ComponentActivity class implements LifecycleOwner.
    • ReportFragment. Injectifneedin (this) was called in the onCreate method; ReportFragment was injected. Get the mlifcycleregistry object through getLifecycle!
    • Lifecycle is an abstract class, and lifecycle registry is its implementation subclass, which is mainly used to manage the Observer,
    @RestrictTo(LIBRARY_GROUP)
    public class ComponentActivity extends Activity implements LifecycleOwner {
    
        private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    
        @Override
        @SuppressWarnings("RestrictedApi")
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ReportFragment.injectIfNeededIn(this);
        }
    
        @CallSuper
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            mLifecycleRegistry.markState(Lifecycle.State.CREATED);
            super.onSaveInstanceState(outState);
        }
    
        @Override
        public Lifecycle getLifecycle() {
            return mLifecycleRegistry;
        }
    }
    
    public class LifecycleRegistry extends Lifecycle {}
    
    public abstract class Lifecycle {}
    

05. How annotation methods are called

  • Onlife event annotation:
    • It can be seen that there is a RetentionPolicy.RUNTIME modifier, which indicates the runtime annotation, which is recognized by reflection at runtime.
    • Runtime annotation is generally used in combination with reflection mechanism. Compared with compile time annotation, its performance is lower, but it is flexible and easy to implement.
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface OnLifecycleEvent {
        Lifecycle.Event value();
    }
    
  • Before that, when we finished understanding the principle of life cycle monitoring, we also saw that the receiver of life cycle events, lifecycle registry, was its handlelifcycleevent(), which received the events. We continued to trace.
    public void handleLifecycleEvent(Lifecycle.Event event) {
      mState = getStateAfter(event);
      if (mHandlingEvent || mAddingObserverCounter != 0) {
          mNewEventOccurred = true;
          // we will figure out what to do on upper level.
          return;
      }
      mHandlingEvent = true;
      sync();
      mHandlingEvent = false;
    }
    
  • In fact, it can be seen from the method annotation that it processes the state and notifies the observer. Look at the getStateAfter() method:
    • getStateAfter() method gets the corresponding State according to the current Event. In fact, it is the code implementation of the figure in [2.3.3].
    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);
    }
    
  • Next, look at the sync() method:
    private void sync() {
      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();
          }
          Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
          if (!mNewEventOccurred && newest != null
                  && mState.compareTo(newest.getValue().mState) > 0) {
              forwardPass();
          }
      }
      mNewEventOccurred = false;
    }
    
  • The sync method compares the current mState with the previous State to see whether it should move forward or backward, which corresponds to the forward and backward of the life cycle. For example, from onresume to onpause (forward pass), onpause to onresume (backward pass), take backwardPass() as an example. (the forwardPass method works similarly)
    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()))) {
              //Call downEvent to get the previous Event
              Event event = downEvent(observer.mState);
              pushParentState(getStateAfter(event));
              //Distribute Event 
              observer.dispatchEvent(lifecycleOwner, event);
              popParentState();
          }
      }
    }
    
    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);
    }
    
  • As you can see from the source code, the backwardPass() method calls downEvent to get the target Event for fallback. It may be more abstract. For example, in the onResume state, we press home. At this time, the RESUMED state changes to the STARTED state. The corresponding Event to be sent is on ﹣ pause. This is the backwardPass() logic. If the preceding codes are all introducers, we will finally see a trace of distribution - observer. DispatchEvent (lifecycle owner, Event).
    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);
            //Here
            mLifecycleObserver.onStateChanged(owner, event);
            mState = newState;
        }
    }
    
  • You can see that you finally called the GenericLifecycleObserver.onStateChanged() method and followed it.
    • This class has a lot of code, but it's not complicated. You can see that the final code goes to invokeCallback(), calling the method through reflection.
    • This method is the method modified by the onlifcycleevent annotation found by the reflection traversing our registered Observer method in the createInfo() method, and is stored in info.mEventToHandlers according to the Event type.
    • The method decorated with annotation in the Observer will be obtained by reflection and saved, and then the corresponding Event method will be found when the life cycle changes, and the method will be called by reflection.
    class ReflectiveGenericLifecycleObserver implements GenericLifecycleObserver {
        //mWrapped is our Observer
        private final Object mWrapped;
        //Reflect mWrapped to get the annotated method
        private final CallbackInfo mInfo;
        @SuppressWarnings("WeakerAccess")
        static final Map<Class, CallbackInfo> sInfoCache = new HashMap<>();
    
        ReflectiveGenericLifecycleObserver(Object wrapped) {
            mWrapped = wrapped;
            mInfo = getInfo(mWrapped.getClass());
        }
    
        @Override
        public void onStateChanged(LifecycleOwner source, Event event) {
            invokeCallbacks(mInfo, source, event);
        }
        
        private void invokeCallbacks(CallbackInfo info, LifecycleOwner source, Event event) {
            invokeMethodsForEvent(info.mEventToHandlers.get(event), source, event);
            invokeMethodsForEvent(info.mEventToHandlers.get(Event.ON_ANY), source, event);
        }
      
        private void invokeMethodsForEvent(List<MethodReference> handlers, LifecycleOwner source,
                Event event) {
            if (handlers != null) {
                for (int i = handlers.size() - 1; i >= 0; i--) {
                    MethodReference reference = handlers.get(i);
                    invokeCallback(reference, source, event);
                }
            }
        }
        //Finally, go to invokeCallback
        private void invokeCallback(MethodReference reference, LifecycleOwner source, Event event) {
            //noinspection TryWithIdenticalCatches
            try {
                switch (reference.mCallType) {
                    case CALL_TYPE_NO_ARG:
                        reference.mMethod.invoke(mWrapped);
                        break;
                    case CALL_TYPE_PROVIDER:
                        reference.mMethod.invoke(mWrapped, source);
                        break;
                    case CALL_TYPE_PROVIDER_WITH_EVENT:
                        reference.mMethod.invoke(mWrapped, source, event);
                        break;
                }
            } catch (InvocationTargetException e) {
                throw new RuntimeException("Failed to call observer method", e.getCause());
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
      
        private static CallbackInfo getInfo(Class klass) {
            CallbackInfo existing = sInfoCache.get(klass);
            if (existing != null) {
                return existing;
            }
            existing = createInfo(klass);
            return existing;
        }
        
        //Get method information through reflection
        private static CallbackInfo createInfo(Class klass) {
            //...
            Method[] methods = klass.getDeclaredMethods();
    
            Class[] interfaces = klass.getInterfaces();
            for (Class intrfc : interfaces) {
                for (Entry<MethodReference, Event> entry : getInfo(intrfc).mHandlerToEvent.entrySet()) {
                    verifyAndPutHandler(handlerToEvent, entry.getKey(), entry.getValue(), klass);
                }
            }
    
            for (Method method : methods) {
                OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
                if (annotation == null) {
                    continue;
                }
                Class<?>[] params = method.getParameterTypes();
                int callType = CALL_TYPE_NO_ARG;
                if (params.length > 0) {
                    callType = CALL_TYPE_PROVIDER;
                    if (!params[0].isAssignableFrom(LifecycleOwner.class)) {
                        throw new IllegalArgumentException(
                                "invalid parameter type. Must be one and instanceof LifecycleOwner");
                    }
                }
                Event event = annotation.value();
                //...
                MethodReference methodReference = new MethodReference(callType, method);
                verifyAndPutHandler(handlerToEvent, methodReference, event, klass);
            }
            CallbackInfo info = new CallbackInfo(handlerToEvent);
            sInfoCache.put(klass, info);
            return info;
        }
    
        @SuppressWarnings("WeakerAccess")
        static class CallbackInfo {
            final Map<Event, List<MethodReference>> mEventToHandlers;
            final Map<MethodReference, Event> mHandlerToEvent;
    
            CallbackInfo(Map<MethodReference, Event> handlerToEvent) {
                //...
            }
        }
    
        static class MethodReference {
            final int mCallType;
            final Method mMethod;
    
            MethodReference(int callType, Method method) {
                mCallType = callType;
                mMethod = method;
                mMethod.setAccessible(true);
            }
        }
    
        private static final int CALL_TYPE_NO_ARG = 0;
        private static final int CALL_TYPE_PROVIDER = 1;
        private static final int CALL_TYPE_PROVIDER_WITH_EVENT = 2;
    }
    

06.addObserver call analysis

  • Take a look at the addObserver method in Lifecycle and find out that it is an abstract method. Then go to its implementation class. First, take a look at the implementation code of addObserver method in the Lifecycle registry class
    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        //Construct observer with state
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        //Add the observer object and statefulObserver object to the fastsafeiterable map data structure
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
    
        if (previous != null) {
            return;
        }
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        if (lifecycleOwner == null) {
            // It's null, we should be destroyed. Fast regression
            return;
        }
    
        boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
        State targetState = calculateTargetState(observer);
        mAddingObserverCounter++;
        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--;
    }
    
  • Then take a look at the ObserverWithState class, trace the code to lifecycle.getcallback (observer), and see what has been done in it
    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;
        }
    }
    
  • Next let's look at the getCallback method in the lifecycle class
    • Determine whether the Observer is a generic lifecycle Observer. If yes, it will return to itself. If it is a fulllifecycle Observer, a fulllifecycle Observer adapter object will be created directly
    • Judge whether the annotation processor is included. Find whether the class containing "class name" and "lifecycle adapter" contain and have OnLifecycleEvent annotation. Then return singlegeneratedadapterobserver / compositegeneratedadapterobserver
    • Call the callback method through reflection if none of the above commits are satisfied
    @NonNull
    static GenericLifecycleObserver getCallback(Object object) {
        if (object instanceof FullLifecycleObserver) {
            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object);
        }
    
        if (object instanceof GenericLifecycleObserver) {
            return (GenericLifecycleObserver) object;
        }
        
        //Get the Class object of the incoming object
        final Class<?> klass = object.getClass();
        //Gets whether the type contains an annotation handler
        int type = getObserverConstructorType(klass);
        if (type == GENERATED_CALLBACK) {
            ////In this case, the include annotation processor returns SingleGeneratedAdapterObserver or compositegeneratedadapterobserver
            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);
        }
        ///Calling methods through reflection
        return new ReflectiveGenericLifecycleObserver(object);
    }
    
  • Then look at the SingleGeneratedAdapterObserver class
    • The final call through the ObserverWithState#dispatchEvent method is the onStateChanged method in SingleGeneratedAdapterObserver.
    • The callMethods method of Adapter is called in SingleGeneratedAdapterObserver
    • This is
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    public class SingleGeneratedAdapterObserver implements GenericLifecycleObserver {
    
        private final GeneratedAdapter mGeneratedAdapter;
    
        SingleGeneratedAdapterObserver(GeneratedAdapter generatedAdapter) {
            mGeneratedAdapter = generatedAdapter;
        }
    
        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            mGeneratedAdapter.callMethods(source, event, false, null);
            mGeneratedAdapter.callMethods(source, event, true, null);
        }
    }
    
  • Then take a look at the CompositeGeneratedAdaptersObserver class
    • The final call through the ObserverWithState#dispatchEvent method is the onStateChanged method in CompositeGeneratedAdaptersObserver.
    • Traverse the mGeneratedAdapters in compositegeneratedbadaptersobserver, and then call the callMethods method
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    public class CompositeGeneratedAdaptersObserver implements GenericLifecycleObserver {
    
        private final GeneratedAdapter[] mGeneratedAdapters;
    
        CompositeGeneratedAdaptersObserver(GeneratedAdapter[] generatedAdapters) {
            mGeneratedAdapters = generatedAdapters;
        }
    
        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            MethodCallsLogger logger = new MethodCallsLogger();
            for (GeneratedAdapter mGenerated: mGeneratedAdapters) {
                mGenerated.callMethods(source, event, false, logger);
            }
            for (GeneratedAdapter mGenerated: mGeneratedAdapters) {
                mGenerated.callMethods(source, event, true, logger);
            }
        }
    }
    
  • Finally, take a look at the code of the reflectivegenericlycleobserver class
    • The reflection calls the callback function, but I've heard about the class object here, getting the info information from the ClassesInfoCache. Take it from the map first. You can't get the methods in the class scanned by the createInfo function. See the source code for specific analysis
    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);
        }
    }
    
  • When addObserver is finally imported, it is a wrapped ObserverWithState object and then calls the onStateChanged method to distribute the state. Use the processor to improve performance and avoid performance consumption caused by reflection.

07. Sort out and summarize the knowledge points

  • The Lifecycle library senses the life cycle by injecting ReportFragment into onCreate of SupportActivity;
  • Lifecycle abstract class is one of the core classes of lifecycle library. It is an abstraction of lifecycle. It defines lifecycle events and states. Through it, we can get the current lifecycle state, and it also lays the keynote of observer mode. (I'm a party member, can you see: - D)
  • Lifecycle owner describes a component with a lifecycle, which can be defined by itself, but usually we don't need to directly use AppCompatActivity, etc;
  • LifecycleRegistry is the implementation class of Lifecycle. It is responsible for taking over the Lifecycle events, as well as the registration and notification of Observer;
  • ObserverWithState is a encapsulation class of Observer. It calls our methods decorated with annotations through reflective generic lifecycle observe;
  • Lifecycle observer, the observer of lifecycle, with which we can enjoy the capabilities brought by lifecycle;
  • Reflective generic lifecycle Observer, which stores the methods we annotated in the Observer, and finally calls the corresponding methods through reflection when the lifecycle changes.

Reference blog

  • https://developer.android.com/topic/libraries/architecture/lifecycle
  • https://www.jianshu.com/p/7087f1dae359
  • https://mp.weixin.qq.com/s/P22w7K0vS5s0A9M4HkBgzQ
  • https://mp.weixin.qq.com/s/xxYoyLXIIr8zHMz9BbpnAg

Open source LiveData event bus: https://github.com/yangchong211/YCLiveDataBus

173 original articles published, 75 praised, 110000 visitors+
Private letter follow

Posted by wangsc66 on Sun, 08 Mar 2020 19:37:25 -0700