Lifecycle详细分析
Lifecycle源码分析
目录介绍
- 01.Lifecycle的作用是什么
- 02.Lifecycle的简单使用
- 03.Lifecycle的使用场景
- 04.如何实现生命周期感知
- 05.注解方法如何被调用
- 06.addObserver调用分析
- 07.知识点梳理和总结一下
00.使用AAC实现bus事件总线
- 利用LiveData实现事件总线,替代EventBus。充分利用了生命周期感知功能,可以在activities, fragments, 或者 services生命周期是活跃状态时更新这些组件。支持发送普通事件,也可以发送粘性事件;还可以发送延迟消息,以及轮训延迟消息等等。
- https://github.com/yangchong211/YCLiveDataBus
01.Lifecycle的作用是什么
- Lifecycle 是一个专门用来处理生命周期的库,它能够帮助我们将 Activity、Fragment 的生命周期处理与业务逻辑处理进行完全解耦,让我们能够更加专注于业务;通过解耦让 Activity、Fragment 的代码更加可读可维护。
02.Lifecycle的简单使用
- 直接看一下下面的案例,用法十分简单,代码如下
- 可以通过 getLifecycle() 方法拿到 Lifecycle, 并添加 Observer 来实现对 Activity 生命周期的监听。
- 然后打印日志记录如下所示
- 可以发现Lifecycle是可以监听activity的生命周期的。
- 在activity创建的时候,activity中生命周期onCreate方法优先LifecycleObserver中onCreate方法先执行;关闭的时候相反!
03.Lifecycle的使用场景
- Lifecycle 的应用场景非常广泛,我们可以利用 Lifecycle 的机制来帮助我们将一切跟生命周期有关的业务逻辑全都剥离出去,进行完全解耦。
- 比如视频的暂停与播放,
- Handler 的消息移除,
- 网络请求的取消操作,
- Presenter 的 attach&detach View
- 暂停和恢复动画绘制
- 并且可以以一个更加优雅的方式实现,还我们一个更加干净可读的 Activity & Fragment。
- 关于网络请求的取消操作
- 停止和开启视频缓冲
- 使用支持生命周期的组件尽快开始视频缓冲,但是将播放推迟到应用程序完全启动。 还可以使用可识别生命周期的组件在应用程序销毁时终止缓冲。
- 启动和停止网络连接
- 使用可感知生命周期的组件可以在应用程序处于前台状态时实时更新(流式传输)网络数据,并在应用程序进入后台时自动暂停。
- 暂停和恢复动画绘制
- 当应用程序在后台运行时,使用生命周期感知组件处理暂停动画绘制,并在应用程序在前台运行后恢复绘制。
04.如何实现生命周期感知
- 看到上面的简单案例,可以发现使用了注解@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)标注的方法,既可以执行生命周期的监听。
- 那么追踪到Lifecycle.Event类,看看还有哪里使用到了该注解,截图如下所示,这里我们就先看一下ReportFragment类,看上去应该跟Fragment有关系!
4.1 生命周期事件与状态
- 上面案例中使用到了注解,那么它究竟有那些状态呢?
- Lifecycle是一个抽象类,里面主要有两个功能,一个是Event生命周期,一个是State状态。
- Lifecycle.Event表示生命周期的状态,与 Activity 生命周期类似。
- Lifecycle.State表示当前组件的生命周期状态,
- Event 与 State 的关系(摘自网络)
4.2 ReportFragment类分析
- 源码如下所示,这里只是摘取了部分和生命周期有关的源代码。
- 重写了生命周期回调的方法,可以看到生命周期方法中调用了dispatch(Lifecycle.Event.XXX),是这个 ReportFragment 在发挥作用。
- Lifecycle 利用了 Fragment 来实现监听生命周期,并在最终利用 dispatch 的方法来分发生命周期事件。
- 在Fragment生命周期发生变化时调用dispatch方法来分发生命周期,在里面调用了LifecycleRegistry的handleLifecycleEvent方法。
- 然后再来看一下哪里用到了这个ReportFragment类,具体追踪到LifecycleDispatcher中的DispatcherActivityCallback内部类中的onActivityCreated方法,源码如下所示
- 接着看一下handleLifecycleEvent(event)源码代码,可以发现根据Event状态来获取State状态,然后分发状态。后续还会分析到……
4.3 ComponentActivity类分析
- fragment需要依赖宿主activity。通过搜索ReportFragment.injectIfNeededIn调用地方,发现 ComponentActivity 调用了该方法。(API 28 以下的版本是 SupportActivity )
- 内部创建了一个 LifecycleRegistry 成员对象,并且该ComponentActivity类实现了 LifecycleOwner 。
- 在 onCreate 方法里 调用了 ReportFragment.injectIfNeededIn(this); 注入了 ReportFragment。通过getLifecycle可以获取mLifecycleRegistry对象!
- Lifecycle是一个抽象类,LifecycleRegistry是它的实现子类,主要是管理Observer,
05.注解方法如何被调用
- OnLifecycleEvent 注解:
- 看到有 RetentionPolicy.RUNTIME 修饰,表示运行时注解,在运行时通过反射去识别的注解。
- 运行时注解一般和反射机制配合使用,相比编译时注解性能比较低,但灵活性好,实现起来比较简单。
- 之前在了解完生命周期监听的原理的同时,我们也看到了生命周期事件的接收者 LifecycleRegistry ,是它的 handleLifecycleEvent() 接收了事件,我们继续追踪。
- 其实从方法注释就能看出来了,就是它处理了状态并通知了 observer 。看下 getStateAfter() 方法:
- getStateAfter() 这个方法根据当前 Event 获取对应的 State ,细看其实就是 【2.3.3】中那个图的代码实现。
- 接下去看 sync() 方法:
- sync 方法里对比了当前 mState 以及上一个 State ,看是应该前移还是后退,这个对应了生命周期的前进跟后退,打个比方就是从 onResume -> onPause (forwardPass),onPause -> onResume (backwardPass),拿 backwardPass() 举例吧。(forwardPass方法处理类似)
- 通过源码可以看到, backwardPass() 方法调用 downEvent 获取往回退的目标 Event。可能比较抽象,举个例子,在 onResume 的状态,我们按了 home,这个时候就是 RESUMED 的状态变到 STARTED 的状态,对应的要发送的 Event 是 ON_PAUSE,这个就是 backwardPass() 的逻辑了。如果前面的代码都是引子的话,最终看到了一丝分发的痕迹了—— observer.dispatchEvent(lifecycleOwner, event)。
- 可以看到最后调用了 GenericLifecycleObserver.onStateChanged() 方法,再跟。
- 这个类的代码比较多,不过也不复杂。可以看到最后代码走到了invokeCallback() ,通过反射调用了方法。
- 而这个方法是 createInfo() 方法中反射遍历我们注册的 Observer 的方法找到的被 OnLifecycleEvent 注解修饰的方法,并且按 Event 类型存储到了 info.mEventToHandlers 里。
- 在 Observer 用注解修饰的方法,会被通过反射的方式获取,并保存下来,然后在生命周期发生改变的时候再找到对应 Event 的方法,通过反射来调用方法。
06.addObserver调用分析
- 看一下Lifecycle中addObserver方法,发现它是一个抽象方法,那么就去找它的实现类,这里先来看一下LifecycleRegistry类中的addObserver方法实现代码
- 然后看一下ObserverWithState类,追溯代码到Lifecycling.getCallback(observer),看看里面做了什么
- 接着来看看Lifecycling类中getCallback方法
- 判断该Observer是否是GenericLifecycleObserver,是的话返回本身;如果是FullLifecycleObserver,则直接创建一个FullLifecycleObserverAdapter对象
- 判断是否包含注解处理器 查找是否包含“类名__LifecycleAdapter”的类 包含并且有OnLifecycleEvent注解则返回SingleGeneratedAdapterObserver/CompositeGeneratedAdaptersObserver
- 如果以上提交都不满足就通过反射调用回调方法
- 然后查看一下SingleGeneratedAdapterObserver类
- 通过ObserverWithState#dispatchEvent方法最后调用的实际是SingleGeneratedAdapterObserver里面的onStateChanged方法
- 在SingleGeneratedAdapterObserver里面调用了Adapter的callMethods方法
- 这个是
- 然后看一下CompositeGeneratedAdaptersObserver类
- 通过ObserverWithState#dispatchEvent方法最后调用的实际是CompositeGeneratedAdaptersObserver里面的onStateChanged方法
- 在CompositeGeneratedAdaptersObserver里面遍历mGeneratedAdapters,然后也是调用callMethods方法
- 最后看一下ReflectiveGenericLifecycleObserver类的代码
- 反射调用回调函数,不过这里听过class对象,从ClassesInfoCache获取info信息。先从map里拿,拿不到通过createInfo函数扫描类里面的方法。具体分析可以看源码……
- 当addObserver的时候最后实际传入的是一个包装好的ObserverWithState对象 然后调用onStateChanged方法来分发状态。使用处理器来提高性能,避免反射造成的性能消耗。
07.知识点梳理和总结一下
- Lifecycle 库通过在 SupportActivity 的 onCreate 中注入 ReportFragment 来感知发生命周期;
- Lifecycle 抽象类,是 Lifecycle 库的核心类之一,它是对生命周期的抽象,定义了生命周期事件以及状态,通过它我们可以获取当前的生命周期状态,同时它也奠定了观察者模式的基调;(我是党员你看出来了吗:-D)
- LifecycleOwner ,描述了一个拥有生命周期的组件,可以自己定义,不过通常我们不需要,直接使用 AppCompatActivity 等即可;
- LifecycleRegistry 是Lifecycle的实现类,它负责接管生命周期事件,同时也负责Observer` 的注册以及通知;
- ObserverWithState ,是 Observer 的一个封装类,是它最终 通过 ReflectiveGenericLifecycleObserve 调用了我们用注解修饰的方法;
- LifecycleObserver ,Lifecycle 的观察者,利用它我们可以享受 Lifecycle 带来的能力;
- ReflectiveGenericLifecycleObserver,它存储了我们在 Observer 里注解的方法,并在生命周期发生改变的时候最终通过反射的方式调用对应的方法。
参考博客
- 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
开源LiveData事件总线:https://github.com/yangchong211/YCLiveDataBus
Lifecycle详细分析的更多相关文章
- ZIP压缩算法详细分析及解压实例解释
最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据 ...
- 1125MySQL Sending data导致查询很慢的问题详细分析
-- 问题1 tablename使用主键索引反而比idx_ref_id慢的原因EXPLAIN SELECT SQL_NO_CACHE COUNT(id) FROM dbname.tbname FORC ...
- LinkedList详细分析
一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据remove()7.数据获取get()8.数据复制clo ...
- android ListView 九大重要属性详细分析、
android ListView 九大重要属性详细分析. 1.android ListView 一些重要属性详解,兄弟朋友可以参考一下. 首先是stackFromBottom属性,这只该属性之后你做好 ...
- C语言中的static 详细分析
转自:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇大 ...
- Linux内核OOM机制的详细分析(转)
Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典 ...
- Android-Native-Server 启动和注册详细分析
Android-Native-Server 启动和注册详细分析 以mediaService为实例来讲解: mediaService的启动入口 是一个 传统的 main()函数 源码位置E:\ ...
- px,dp,dip,sp,in,mm,pt详细分析
px,dp,dip,sp,in,mm,pt详细分析 px :(pixels),屏幕的像素点,不同的设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多. dip :(devi ...
- Http Pipeline详细分析(下)
Http Pipeline详细分析(下) 文章内容 接上面的章节,我们这篇要讲解的是Pipeline是执行的各种事件,我们知道,在自定义的HttpModule的Init方法里,我们可以添加自己的事件, ...
- 用户代理检测与浏览器Ua详细分析
用户代理检测与浏览器Ua详细分析:http://www.cnblogs.com/hykun/p/Ua.html
随机推荐
- Linux zip常用命令
1.将当前目录下的所有文件和文件夹全部压缩成myfile.zip内联代码块文件zip -r myfile.zip ./*-r表示递归压缩子目录下所有文件. 2.unzip把myfile.zip文件解压 ...
- sensitive-word v0.13 特性版本发布 支持英文单词全词匹配
拓展阅读 sensitive-word-admin v1.3.0 发布 如何支持分布式部署? sensitive-word-admin 敏感词控台 v1.2.0 版本开源 sensitive-word ...
- 51单片机(STC89C52)在Ubuntu下的开发
简介 都是8051衍生的8位单片机, STC单片机有89/90/10/11/12/15这几个大系列, 每个系列的特点如下 89系列是传统的8051单片机, 烧录方法有区别, 但是功能上可以和AT89系 ...
- 【Unity3D】花瓣特效
1 花瓣绘制原理 如下图是实现的花瓣特效效果,为方便描述,我们将每个红色的扁状长条称为花瓣,每个花瓣中心的绿点称为花蕊,花朵的正中心称为花心. 我们在 xOz 平面上绘制花朵,假设花心为 O ...
- Event对象
Event对象 Event对象表示在DOM中出现的事件,在DOM中有许多不同类型的事件,其主要使用基于Event对象作为主接口的二次接口,Event对象本身包含适用于所有事件的属性和方法. 描述 事件 ...
- Laravel入坑指南(3)——模板
各位小伙伴有缘聚到这里,说明对于Laravel的路由和控制器已经有点了解了. 会写业务逻辑之后,如何把结果漂亮地展示出来,就是我们要解决的问题.(前后端分离的同学,请自动忽略)在MVC的世界里,漂亮的 ...
- js根据输入字符长度自动调整textarea高度
1.编写html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- IDA 反汇编 explorer
之前写过一篇关于 IDA 在无 dmp 文件下如何定位到崩溃点的文章,由于其中涉及到公司项目,就仅限自己看了 正好今天看到一篇关于火绒软件误杀 explorer 的文章,并且有相关的复现过程 文章已经 ...
- Notepad++找回自动保存缓存内容的文件
在目录C:\Users\Administrator\AppData\Roaming\Notepad++\backup中找到自动保存的缓存文件. 参考Notepad++找回自动保存缓存内容的文件
- ThreadLocal的应用场景和注意事项有哪些?
https://cloud.tencent.com/developer/article/1618405