Jetpack组件之Lifecycle使用与源码分析

Posted 涂程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jetpack组件之Lifecycle使用与源码分析相关的知识,希望对你有一定的参考价值。

Lifecycle的作用

它是用来监听Activity和Fragment的生命周期的,非常好用,可以让我们解耦一些业务代码,以及更方便地监测生命周期。

比如说,我有这样一个需求:记录部分页面的用户浏览时长,并且上报给服务器。

如果不用Lifecycle,也能实现这样的需求

 class RecordActivity : AppCompatActivity() 
     var startTime = 0L
     override fun onCreate(savedInstanceState: Bundle?) 
         startTime = System.currentTimeMillis()
     
     
     override fun onDestroy() 
         val browseTime = System.currentTimeMillis() - startTime
         //上报服务器。。。
     
 

以上就实现了一个页面的上报,但是我不止这一个界面需要上报时长啊。我们可能就会考虑到,把这个代码抽出来放到BaseActivity中,然后所有Activity都继承BaseActivity,再提供一个flag作为是否需要上报的开关就OK啦。确实不错,但是不够优雅,且结构改动大,有侵入性。
那用Lifecycle如何实现呢?

 class RecordActivity : AppCompatActivity() 
 
     override fun onCreate(savedInstanceState: Bundle?) 
         getLifecycle().addObserver(ReportObserver())
     
 
 
 
 class ReportObserver : LifecycleObserver 
 
     var startTime = 0L
 
     @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
     fun connectListener() 
         startTime = System.currentTimeMillis()
     
 
     @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
     fun disconnectListener() 
         val browseTime = System.currentTimeMillis() - startTime
         //上报服务器。。。
     
 

ReportObserver继承LifecycleObserver,通过注解@OnLifecycleEvent(…)监听ON_CREATE和ON_DESTROY,从而完成解耦,这样的实现方式相比于第一种要好很多。
接下来看看它是怎么实现的。
Lifecycle原理解析

基于lifecycle-common:2.2.0

步骤1:ComponentActivity#getLifecycle()

在AppCompatActivity中我们可以直接调用getLifecycle(),获取Lifecycle对象,实际上这是ComponentActivity的方法

 public class ComponentActivity 
     private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
 
     public Lifecycle getLifecycle() 
         return mLifecycleRegistry;
     
 

可以看到getLifecycle()返回的是LifecycleRegistry对象。
步骤2:LifecycleRegistry#addObserver()
来到LifecycleRegistry内部,查看一下addObserver()方法

 @Override
 public void addObserver(@NonNull LifecycleObserver observer) 
     State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
     ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
     ...
     while (...) 
         ...
         statefulObserver.dispatchEvent(lifecycleOwner, event);
         ...
     
     ...
 

省略了部分代码,我们可以看到,addObserver()方法内部并没有做什么特殊的处理,其中

 ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);

将传入的observer封装成了ObserverWithState

再往下走就是一个while()循环,然后dispatchEvent()下发了什么状态,然后这个Observer就添加完毕了。那下一步就是要找到,什么时候触发这个Observer的回调。

步骤3:debug

在这一步,我选择在回调处打上断点进行观察。以Lifecycle.Event.ON_CREATE事件为切入点作分析
得到以下方法栈

 connectListener:28, ReportObserver (com.fun.sheet)
 invoke:-1, Method (java.lang.reflect)
 invokeCallback:216, ClassesInfoCache$MethodReference (androidx.lifecycle)
 invokeMethodsForEvent:194, ClassesInfoCache$CallbackInfo (androidx.lifecycle)
 invokeCallbacks:185, ClassesInfoCache$CallbackInfo (androidx.lifecycle)
 onStateChanged:37, ReflectiveGenericLifecycleObserver (androidx.lifecycle)
 dispatchEvent:354, LifecycleRegistry$ObserverWithState (androidx.lifecycle)
 forwardPass:265, LifecycleRegistry (androidx.lifecycle)
 sync:307, LifecycleRegistry (androidx.lifecycle)
 moveToState:148, LifecycleRegistry (androidx.lifecycle)
 handleLifecycleEvent:134, LifecycleRegistry (androidx.lifecycle)
 dispatch:68, ReportFragment (androidx.lifecycle)
 onActivityPostCreated:178, ReportFragment$LifecycleCallbacks (androidx.lifecycle)
 dispatchActivityPostCreated:1265, Activity (android.app)
 performCreate:8094, Activity (android.app)
 performCreate:8073, Activity (android.app)
 callActivityOnCreate:1320, Instrumentation (android.app)
 performLaunchActivity:3870, ActivityThread (android.app)
 handleLaunchActivity:4076, ActivityThread (android.app)

我们知道启动一个Activity是跨进程的,Activity由AMS管理。

所以最下方的栈信息

 handleLaunchActivity:4076, ActivityThread(android.app)

是系统方法,处于android.app中,那从下往上推,一直到

 dispatchActivityPostCreated:1265, Activity (android.app)

都是系统方法,由方法名也可以看出dispatchActivityPostCreated()表示要分发Activity的onCreate()事件。我们来看一下相关的代码

步骤4:Activity#dispatchActivityPostCreated()

 private void dispatchActivityPostCreated(@Nullable Bundle savedInstanceState) 
     //收集所有的ActivityLifecycleCallbacks回调对象
     Object[] callbacks = collectActivityLifecycleCallbacks();
     if (callbacks != null) 
         for (int i = 0; i < callbacks.length; i++) 
             //对所有的回调执行onActivityPostCreated()方法
             ((Application.ActivityLifecycleCallbacks) callbacks[i]).onActivityPostCreated(this,
                     savedInstanceState);
         
     
     ...
 

这一步很容易理解,就是常规的回调。让我们回到步骤3中的方法栈图片,在执行回调的过程中,冒出来了一个

 onActivityPostCreated:178, ReportFragment$LifecycleCallbacks (androidx.lifecycle)

哎?看包名这可不是属于android.app了,而是androidx.lifecycle中的类。这个ReportFragment是什么呢?它又是怎么成功执行回调的呢?这个问题后续会随着代码的深入得到解答,我们先继续跑流程

步骤5:ReportFragment.LifecycleCallbacks#onActivityPostCreated()

在步骤4中执行的是ReportFragment.LifecycleCallbacks的onActivityPostCreated()方法,LifecycleCallbacks是ReportFragment的内部类,它继承自Application.ActivityLifecycleCallbacks,它的相关代码如下

 @Override
 public void onActivityPostCreated(@NonNull Activity activity,
         @Nullable Bundle savedInstanceState) 
     dispatch(activity, Lifecycle.Event.ON_CREATE);
 

可以看到就是一个dispatch()方法,传入的第二个参数为Lifecycle.Event.ON_CREATE。接着我们按照步骤3的方法栈继续往上追

步骤6:ReportFragment#dispatch()

 static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) 
     ...
     if (activity instanceof LifecycleOwner) 
         Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
         if (lifecycle instanceof LifecycleRegistry) 
             //关键代码
             ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
         
     
 

继续来到了ReportFragment#dispatch()方法,在其内部执行了LifecycleRegistry的handleLifecycleEvent()方法,把事件继续分发给LifecycleRegistry

步骤7:LifecycleRegistry#handleLifecycleEvent()

这一步,我们接着方法栈信息追踪看看

 public void handleLifecycleEvent(@NonNull Lifecycle.Event event) 
     ...//接着调用moveToState方法
     moveToState(event.getTargetState());
 
 
 private void moveToState(State next) 
     ...
     //再调用sync()方法
     sync();
     ...
 
 
 private void sync() 
     LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
     while (!isSynced()) 
         //读源码时无需深入每一行代码,按照主要流程走即可,这里省略了部分代码
         forwardPass(lifecycleOwner);
     
 
 
 private void forwardPass(LifecycleOwner lifecycleOwner) 
     ...
     while (...) 
         while (...) 
             ObserverWithState observer = entry.getValue();
             //遍历所有observer,调用dispatchEvent()方法,
             //步骤二说过Observer传入的时候会被包装成ObserverWithState,所以接下来进入ObserverWithState#dispatchEvent()
             observer.dispatchEvent(lifecycleOwner, event);
         
     
 

步骤8:ObserverWithState#dispatchEvent()

 //ObserverWithState是LifecycleRegistry的一个内部类
 static class ObserverWithState 
     State mState;
     LifecycleEventObserver mLifecycleObserver;
     
     //看一下他的构造方法,步骤二说过ReportObserver被包装成了ObserverWithState,调用的就是这个构造方法
     ObserverWithState(LifecycleObserver observer, State initialState) 
         //可以看到,ReportObserver在被调用了Lifecycling.lifecycleEventObserver()方法后成为了LifecycleEventObserver保存在了ObserverWithState内部
         mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
         mState = initialState;
     
     
     //续上步骤7,我们要找的方法在这里
     void dispatchEvent(LifecycleOwner owner, Event event) 
         ...
         //关键方法,接步骤9
         mLifecycleObserver.onStateChanged(owner, event);
         ...
     
 

这一步的信息比较多,但是这里先不展开,后续会有分析。主要是ObserverWithState的构造方法中调用了Lifecycling.lifecycleEventObserver()方法,返回的对象是LifecycleEventObserver,我们根据步骤3的栈信息可以知道这个LifecycleEventObserver指向的是ReflectiveGenericLifecycleObserver,那我们继续往下走。

步骤9:ReflectiveGenericLifecycleObserver#onStateChanged()

 class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver 
     private final Object mWrapped;
     private final CallbackInfo mInfo;
 
     ReflectiveGenericLifecycleObserver(Object wrapped) 
         mWrapped = wrapped;
         mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
     
 
     @Override
     public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) 
         //mInfo为ClassesInfoCache的内部类CallbackInfo的示例,看构造方法可知,跟上步骤9
         mInfo.invokeCallbacks(source, event, mWrapped);
     
 

onStateChanged()方法中调用了mInfo.invokeCallbacks(),这个mInfo也比较清晰,在ReflectiveGenericLifecycleObserver的构造方法中也表明了,它是ClassesInfoCache.sInstance.getInfo()返回的结果,这里也是先不管它,继续看步骤3栈信息,得知mInfo指向ClassesInfoCache的内部类CallbackInfo,继续往下看。

步骤10:

ClassesInfoCache.CallbackInfo#invokeCallbacks

 void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) 
     //继续调用
     invokeMethodsForEvent(mEventToHandlers.get(event), 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可以看到是MethodReference集合,而MethodReference也是ClassesInfoCache内部类,接着跟步骤11
             handlers.get(i).invokeCallback(source, event, mWrapped);
         
     
 

这步没啥,继续跟步骤11

步骤11:ClassesInfoCache.MethodReference#invokeCallback()

 static final class MethodReference 
     final int mCallType;
     final Method mMethod;
     
     MethodReference(int callType, Method method) 
         mCallType = callType;
         mMethod = method;
         mMethod.setAccessible(true);
     
     
     void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) 
         try 
             switch (mCallType) 
                 //代码1
                 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 (...) 
         
     
 

最终执行到代码1,mCallType是CALL_TYPE_NO_ARG。紧接着调用

 mMethod.invoke(target);

很显然,这是通过反射调用的。

mMethod是谁?

还记得我们在ReportObserver中自定义的方法名吗叫做connectListener(),这里就是这个方法的引用

target是谁?

自然是ReportObserver本身。

到这里,整个回调的流程就已经分析完毕了。

总体流程就是ReportObserver中的自定义方法,加上特定的生命周期注解,就会调用反射拿到这个方法的引用,AMS启动Activity后会通知所有的监听者回调对应的生命周期方法,对于androidx.lifecycle库而言,ReportFragment是处理生命周期方法的入口,最终完成回调。

虽然流程走完了,但其实我们留下了很多问题有待解决。那接着往下看

问题1:在哪执行反射的?也就是mMethod引用怎么初始化的

让我们回看一下步骤2中的

 ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);

我们提到,ReportObserver又被包装成了ObserverWithState,看起来是多次一举,其实不然。在步骤8中我们贴出了ObserverWithState的构造方法,这里再贴一遍

 static class ObserverWithState 
     State mState;
     LifecycleEventObserver mLifecycleObserver;
     ObserverWithState(LifecycleObserver observer, State initialState) 
         //在构造方法中调用了Lifecycling.lifecycleEventObserver(),传入的参数是ReportObserver。
         mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
         mState = initialState;
     
 

这里的Lifecycling.lifecycleEventObserver(observer),我们有必要分析一下

标记1 - Lifecycling.lifecycleEventObserver()

 @NonNull
 static LifecycleEventObserver lifecycleEventObserver(Object object) 
     ...
     final Class<?> klass = object.getClass();
     //代码1
     int type = getObserverConstructorType(klass);
     if (type == GENERATED_CALLBACK)   //GENERATED_CALLBACK值是2
         ...
         return new CompositeGeneratedAdaptersObserver(adapters);
     
     return new ReflectiveGenericLifecycleObserver(object);
 

其中标注的代码1,getObserverConstructorType(klass)值得我们关注,看起来是对class对象的处理,并且返回的type也会对接下来的返回值产生影响

标记2 - Lifecycling.getObserverConstructorType()

 private static int getObserverConstructorType(Class<?> klass) 
     ...
     int type = resolveObserverCallbackType(klass);
     ...省略缓存逻辑
     return type;
 

继续跟进resolveObserverCallbackType()

标记3 - Lifecycling.resolveObserverCallbackType()

 private static int resolveObserverCallbackType(Class<?> klass) 
     ...
     //第一步,生成构造方法,无需关心
     Constructor<? extends GeneratedAdapter> constructor = generatedConstructor(klass);
     if (constructor != null) 
         ...
         return GENERATED_CALLBACK;
     
     //第二步,判断是否存在生命周期方法
     boolean hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass);
     if (hasLifecycleMethods) 
         return REFLECTIVE_CALLBACK;
     
     ...
 

注意,有效信息来了,第二步的处理,引入了ClassesInfoCache类,这正是我们要找的,调用了ClassesInfoCache的hasLifecycleMethods()方法,继续看一下

标记4 - ClassesInfoCache#hasLifecycleMethods()

 boolean hasLifecycleMethods(Class<?> klass) 
     ...缓存逻辑已省略
     //反射拿到ReportObserver中的方法
     Method[] methods = getDeclaredMethods(klass);
     for (Method method : methods) 
         //遍历方法,看是否有@OnLifecycleEvent注解
         OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
         if (annotation != null) 
             //最终调用创建Info的方法
             createInfo(klass, methods);
             return true;
         
     
     ...缓存逻辑
     return false;
 

这个方法很关键,也很容易理解,我们在ReportObserver中的connectListener()是加了@OnLifecycleEvent注解的,所以继续调用createInfo(klass, methods)方法,并且返回了true,来看下createInfo(klass, methods)方法吧

标记5 - ClassesInfoCache#createInfo()

 private CallbackInfo createInfo(Class<?> klass, @Nullable Method[] declaredMethods) 
     ...
     for (Method method : methods) 
         OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
        ...
         Class<?>[] params = method.getParameterTypes();
         int callType = CALL_TYPE_NO_ARG;
         //判断参数有几个,对应不同的callType,就是在这里,指定了callType是无参数的
         if (params

以上是关于Jetpack组件之Lifecycle使用与源码分析的主要内容,如果未能解决你的问题,请参考以下文章

Android jetpack架构组件Lifecycle实战与源码解析

Jetpack 组件之 Lifecycle 使用与浅析

Jetpack 之 LifeCycle 组件使用详解

Android Jetpack 组建介绍——Lifecycler

Jetpack — AAC架构组件之Lifecycle

JetPack架构---Lifecycle生命周期相关与原理