生命周期组件 Lifecycle 源码解析(一)

栏目: Android · 发布时间: 5年前

内容简介:在上篇文章:首先,按照上篇文章所讲,快速搭建环境。添加 Lifecycle 轻量级依赖库:

在上篇文章: Android 生命周期组件 Lifecycle 使用详解 中,我们讲了 Lifecycle 的简单使用,本篇我们来研究下它的源码。

基础环境搭建

首先,按照上篇文章所讲,快速搭建环境。

添加 Lifecycle 轻量级依赖库:

implementation "android.arch.lifecycle:runtime:1.1.1"

添加 support library 28.0.0 的支持库(希望大家能先保持一致,因为不同版本的源码是有区别的,后面会将到):

implementation 'com.android.support:appcompat-v7:28.0.0'

再添加个注解处理器相关的依赖,至于用处,后面会讲:

annotationProcessor "android.arch.lifecycle:compiler:1.1.1"

接下来创建实现了 LifecycleObserver 接口的 MyObserver 类:

生命周期组件 Lifecycle 源码解析(一)

让我们的 Activity 继承自 AppCompatActivity,并在 onCreate() 方法中通过 getLifecycle().addObserver(new MyObserver()) 绑定 MyObserver :

生命周期组件 Lifecycle 源码解析(一)

核心代码就一句,` getLifecycle().addObserver(new MyObserver())

`,就能让我们创建的 MyObserver 类,拥有生命周期感知能力。我们知道,这里主要的对象就两个。一个是 getLifecycle() 方法返回来的 LifecycleRegistry 对象(继承自抽象类 Lifecycle),一个是我们创建的需要监听生命周期的类 MyObserver。那我们不禁要问:LifecycleRegistry 是如何感知到生命周期的?它又是如何把生命周期事件分发给 LifecycleObserver 的?

我们先来解决第一个问题,LifecycleRegistry 是如何感知到生命周期的。

LifecycleRegistry 是如何感知到生命周期的

首先,我们 Command/Ctrl + 鼠标左键 跟踪 getLifecycle() 代码,发现它的具体实现是在 AppCompatActivity 的祖先类 SupportActivity 中,该类实现了 LifecycleOwner 接口。

生命周期组件 Lifecycle 源码解析(一)

在 onSaveInstanceState() 方法中将 mLifecycleRegistry 的状态置为了 Lifecycle.State.CREATED,这点我们在前篇也讲到过。但从这我们还是看不到跟生命周期有关的东西。此时,我们发现在 onCreate() 方法中有这一行代码:

ReportFragment.injectIfNeededIn(this);

ReportFragment 是做什么的?点进去看:

生命周期组件 Lifecycle 源码解析(一)

可以看到, ReportFragment 的 injectIfNeededIn(Activity activity) 方法向 Activity 中添加了一个未设置布局的 Fragment :

生命周期组件 Lifecycle 源码解析(一)

然后又在重写的生命周期事件中调用 dispatch(Lifecycle.Event event) 方法,来分发生命周期事件,这就是“生命周期感知能力”的来源。这种通过一个空的 Activity 或者 Fragment 来实现特定功能的技巧还是挺常见的,比如权限请求库 RxPermission ,以及 airbnb 开源的用于URL跳转的 DeepLinkDispatch(前者是使用空的 Fragment,后者使用的是空的 Activity)

ReportFragment#dispatch(Lifecycle.Event event)

生命周期组件 Lifecycle 源码解析(一)

这里面,又调用了 LifecycleRegistry 的 handleLifecycleEvent(event) 方法。至此,就引入了第二个问题,事件是如何分发到 LifecycleObserver 的。

事件是如何分发到 LifecycleObserver 的

进入 LifecycleRegistry#handleLifecycleEvent(Lifecycle.Event event) 方法,发现它又调用了 moveToState(State next) 方法:

生命周期组件 Lifecycle 源码解析(一)

而在 sync() 方法中,根据 state 的状态,最终会调用到 backwardPass(...) 或者 forwardPass(...)

生命周期组件 Lifecycle 源码解析(一)

forwardPass(...) 为例:

生命周期组件 Lifecycle 源码解析(一)

上图可以看到,通过 mObserverMap 最终获取到一个 ObserverWithState 类型的 observer 对象,并调用它的 dispatchEvent 进行事件分发:

observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));

ObserverWithState 又是个什么鬼?我们继续追踪,发现 ObserverWithState 是 LifecycleRegistry 的一个静态内部类。

生命周期组件 Lifecycle 源码解析(一)

从名称上就能看出,该类封装了 Observer 对象和 State 对象(具体就是 StateGenericLifecycleObserver ,GenericLifecycleObserver 是个接口,继承自 LifecycleObserver),在其 dispatchEvent 方法中,最终会回调 mLifecycleObserver 的 onStateChanged(...) 方法。

追踪到这里,我们知道了,Lifecycle在监听到生命周期变化之后,最终会回调 GenericLifecycleObserver 的 onStateChanged() 方法。我们不由得疑惑,我们定义的 MyObserver 哪去了?没看到有调用我们定义的回调方法啊。它和 GenericLifecycleObserver 又有什么关系?

我们看到,ObserverWithState 的构造函数里传进来了一个 LifecycleObserver 类型的 observer 对象,这个参数是从哪传进来的?继续追踪,发现追到了 LifecycleRegistry#addObserver(LifecycleObserver observer) 方法。

而这个方法,就是我们在 MainActivity#onCreate(...) 方法中调用的:

getLifecycle().addObserver(new MyObserver());

到这里,总算跟我们的 MyObserver 关联上了。查看 LifecycleRegistry#addObserver(LifecycleObserver observer) 方法源码:

生命周期组件 Lifecycle 源码解析(一)

这里面的核心代码就两行,一行是:

ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);

这行代码,通过传进来的 Observer 对象,创建出 ObserverWithState 对象。还有一行是:

ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

这行代码是将 LifecycleObserver 对象放入一个FastSafeIterableMap 中,以便进行迭代。

接下来我们就进入 ObserverWithState 的构造方法中看看:

生命周期组件 Lifecycle 源码解析(一)

在构造方法中,通过 Lifecycling.getCallback(observer) 根据传进来的 observer ,构造了一个 GenericLifecycleObserver 类型的 mLifecycleObserver ,那秘密应该也就在这个方法里,继续跟进。

生命周期组件 Lifecycle 源码解析(一)

这个方法的本质,其实就是根据传进来的一个LifecycleObserver 对象,构造出来一个 GenericLifecycleObserver 对象(目前有四个子类: FullLifecycleObserverAdapterSingleGeneratedAdapterObserverCompositeGeneratedAdaptersObserverReflectiveGenericLifecycleObserver ),而最终构造出来的对象,就包含了我们创建的 LifecycleObserver 的所有信息,包括各种回调方法等。

看到这里,就要提到文章开头要大家添加的一个注解处理器的依赖:

annotationProcessor "android.arch.lifecycle:compiler:1.1.1"

当我们通过注解的方式来自定义LifecycleObserver 的时候,按照传统方式,必定要通过反射来对注解进行解析,这样就会对性能造成影响。一方面,我们通过缓存,来避免每次都通过反射获取构造器。另一方面,又通过注解处理器,在编译时对那些被 @OnLifecycleEvent 注解标注的普通方法,进行预处理,生成以“类名_LifecycleAdapter”命名的类,将各种回调方法直接进行逻辑转换,避免反射,进而来提高性能。

明白了这点,再看 Lifecycling.getCallback(observer) 方法就比较容易理解了。

  1. 如果传进来的的参数 object 是 FullLifecycleObserver 类型,就把它构造成FullLifecycleObserverAdapter 对象,并返回
  2. 如果传进来的的参数 object 是GenericLifecycleObserver类型,直接返回该对象
  3. 如果1,2都不满足,就解析该类的的构造器的Type(该类是反射获取的,还是通过注解处理器生成的)。如果是通过注解处理器生成的类来调用回调函数,就返回一个SingleGeneratedAdapterObserver/CompositeGeneratedAdaptersObserver 对象
  4. 如果以上条件都不满足,就通过反射来调用各回调函数。返回一个 ReflectiveGenericLifecycleObserver 对象

现在我们在 app 目录下的 bulid.gradle 中添加上上面的注解处理器依赖,然后编译下项目,会发现在build目录下生成了对应的类: MyObserver_LifecycleAdapter.java

生命周期组件 Lifecycle 源码解析(一)

点进去,看看生成的这个类的源码:

生命周期组件 Lifecycle 源码解析(一)

可以看到,我们在 MyObserver 中通过 @OnLifecycleEvent 注解标注的那些方法,在这里都根据条件进行判断了,而非通过注解。

这时候我们就能理清这个这个流程了,当添加了注解处理器之后,我们这里的 Lifecycling.getCallback(observer) 方法将会把我们的 MyObserver 对象构建成一个 SingleGeneratedAdapterObserver 对象返回(因为这里只有一个构造器),之后的 mLifecycleObserver.onStateChanged(owner, event); 其实调用的就是 SingleGeneratedAdapterObserveronStateChanged(owner, event) 方法:

生命周期组件 Lifecycle 源码解析(一)

这里面就可以看到,它调用了内部包裹的类的 callMethods(...) 方法,也就是我们上面提到的 MyObserver_LifecycleAdaptercallMethonds(...) 方法。

到这里,就完成了 Lifecycle 源码的解析。

通过反射获取注解信息

这顺便提下通过注解的方式调用各回调方法的过程。主要相关类就是 ReflectiveGenericLifecycleObserver.java
生命周期组件 Lifecycle 源码解析(一)

这里我们主要关注回调信息 CallbackInfo 的获取方式的代码: mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());

因为反射的代价是比较大的,所以又通过 ClassesInfoCache.java 这个单例类,为 ReflectiveGenericLifecycleObserver 类要调用的各种方法的相关信息进行了缓存。

点进去看下它的 getInfo(...) 方法内部,是如何获取方法信息的。

生命周期组件 Lifecycle 源码解析(一)

里面又调用了 createInfo() 方法:

生命周期组件 Lifecycle 源码解析(一)

这里,就能看到对注解进行处理的代码了。

到这,我们就算完成了继承自 AppCompactActivity 的情况下的源码解析,而继承自普通 Activity 这种情况下,原理是什么呢?

鉴于篇幅,将放在下篇文章。欢迎关注我的公众号获取。

生命周期组件 Lifecycle 源码解析(一)


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Go Web 编程

Go Web 编程

[新加坡]Sau Sheong Chang(郑兆雄) / 黄健宏 / 人民邮电出版社 / 2017-11-22 / 79

《Go Web 编程》原名《Go Web Programming》,原书由新加坡开发者郑兆雄(Sau Sheong Chang)创作、 Manning 出版社出版,人名邮电出版社引进了该书的中文版权,并将其交由黄健宏进行翻译。 《Go Web 编程》一书围绕一个网络论坛 作为例子,教授读者如何使用请求处理器、多路复用器、模板引擎、存储系统等核心组件去构建一个 Go Web 应用,然后在该应用......一起来看看 《Go Web 编程》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具