1. lifecycle 简介
??在我们的日常开发中,使用Activity 和Fragment 产生的内存泄漏问题比比皆是,主要是原因就是这二者存在生命周期,在走完这一辈子的过程中,有些引用一直抓着着Activity 和Fragment 不放,等到它们Destroy 的时候,依旧引用着它们的尸体,导致不能被回收,因为尸体将一直存在于内存中,导致可用内存减少,然后内存泄漏就开始了。当然了,扯远了,Google废了那么大的劲儿开发了 Jetpack 系列,主要是的原因是为了广大开发者能够写出高质量、高性能的代码,今天这里要说的 lifecycle 就是其中的一个优秀代表了。
那么lifecycle 到底有什么用呢?举个很朴实无华的例子,在MVP架构大行其道时,我们的Presenter 层经常需要感知V 层(即Activity 或者Fragment )的生命周期,在对应的生命周期回调中做些操作,比如在 onDestory 中取消网络请求,关闭数据库等等操作。我们一般的做法是在Activity 的基类中持有 Presenter 的基类,重写Activity 的生命周期回调函数,并在这些回调中调用Presenter 的相应生命周期方法。但是有些组件可能传入的参数并非是Activity ,无法传入一个预定义的类在Activity 相应的生命周期中调用。因为Google 提供了LifeCycle 组件,用于向一个Activity/Fragment 注册生命周期的回调监听。
之所以Google 提供了这种方式,其实就是为了方便开发者无需重写Activity 的生命周期回调方法,直接使用观察者模式对其生命周期进行监听回调。同时Lifecycle 中没有Activity/Fragment 的引用,因此不存在内存泄漏问题。
说了这么多,可能你都没心情看下去,或者一脸懵逼,先来个例子我们试试吧。
2. lifecycle 用法
首先build.gradle :
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0'
首先定义一个类继承自androidx.lifecycle.LifecycleObserver :
class MyCustomObserverBeforeJava8 : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreateX() {
Log.d(TAG,"MyCustomObserver onCreate")
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart(owner : LifecycleOwner) {
Log.d(TAG,"MyCustomObserver onStart : $owner")
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
fun onResume(owner : LifecycleOwner, event : Lifecycle.Event) {
Log.d(TAG,"MyCustomObserver onAny, $owner, $event")
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
Log.d(TAG,"MyCustomObserver onDestroy")
}
companion object {
private val TAG : String = MyCustomObserverBeforeJava8::class.java.simpleName
}
}
注意到我们的每一个方法上面都有一个注解@OnLifecycleEvent ,注解上面都存在一个Lifecycle.Event 事件,一般都能猜到,被 Lifecycle.Event.ON_CREATE 修饰的方法是在 Activity#onCreate() 方法之后调用的的,依次类推,Lifecycle.Event.ON_STAR 、Lifecycle.Event.ON_DESTROY 等等就不说了,如果不是特别的懂,可以使用代码调试调试:
写好了生命周期监听逻辑,剩下的就是去找我们的Activity 建立联系了:
class MyCustomUI : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG," onCreate method")
}
override fun onStart() {
super.onStart()
Log.d(TAG," onStart method")
}
override fun onResume() {
super.onResume()
Log.d(TAG," onResume method")
lifecycle.addObserver(MyCustomObserverBeforeJava8())
}
override fun onDestroy() {
Log.d(TAG,"onDestroy method")
super.onDestroy()
}
companion object {
private val TAG = MyCustomUI::class.java.simpleName
}
}
看一下,就是这么简单,lifecycle 来自androidx.activity.mLifecycleRegistry ,然后就注册了,我们把MyCustomUI 启动起来:
由于我是在Activity#onResume 方法中注册的,因此输出也应该是这样的:先走完Activity#onCreate() onStart() onResume() 然后再执行 我监听MyCustomObserverBeforeJava8 中的 onCreate() onStart() 方法,可能这个比较神奇,或者有违背于我们的思想。我们被拉进了一个新的微信群,按照道理说,我应该看不到我没加入之前的聊天信息,我是在onResume 方法中注册的,Activity的onCreate()、onStart() 应该在我注册之前就已经被执行过了,理论上我是不应该去接受的,但是这个比较奇怪,也算是lifeCycle 中比较奇怪实现方式了,其实它也有一个书面名字叫“倒灌”,这里我们就不重点讨论了,今天的目的是简单的去了解它,理解它的基本原理即可。
3. lifecycle 原理
看了上面的例子,也许你会和我当初想法类似,为啥加个注解就能感知Activity 或者Fragment 的生命周期啊,我都没没有重写过Activity 的生命周期方法啊,它是怎么做到的呢?我们先不去扒源码,想想在lifecycle 之前,我们所使用过的源码中,是否也有过类似的实现方式呢?
了解Glide 的人肯定都知道,Glide 也可以监听Activity 或者Fragment 的生命周期,这是因为Glide 在with 的时候,添加了一个 空白无界面的SupportRequestManagerFragment ,然后通过监听这个SupportRequestManagerFragment 的生命周期方法,从而来监听ImageView 所在的 Activity 的动作变化,从而在各个生命周期中进行ImageView 的请求和销毁。
那我们可以打印一下我们的 MyCustomUI 中存在的fragments :
override fun onResume() {
super.onResume()
supportFragmentManager.fragments.forEach { Log.d(TAG, "current fragment : $it") }
}
打印结果: 这里存在一个ReportFragment ,看吧,天下代码都是相互借鉴的,我估计Google 在开发lifecycle 时或多或少应该借鉴了Glide 内置一个无界面 Fragment 的思想,那么我们就来看看这个ReportFragment 在干嘛什么吧:
public class ReportFragment extends Fragment {
private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"
+ ".LifecycleDispatcher.report_fragment_tag";
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
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);
}
}
正与我们所料,它并没有重写Activity 的生命周期方法,但是它重写了Fragment 的生命周期方法,然后通过这个dispatch 方法将生命周期事件分发出去。到此我们的大方向思路就非常明确了,lifecycle 是通过内置的ReportFrament 来监听生命周期,并将生命周期方法回调分发出去。
其实到了这里,你大概就理解了lifecycle 的工作原理了,出去面试的时候,说到这里如果感觉没啥说的,那么就可以往下看,因为思路虽然简单,但是理解起来还是比较费劲的,可能是Google 的源码工程师写的代码比较深入精髓,想要完全去理解还是需要花一些功夫的。
这里我也不带大家去看源码了,这里我想要自己的语言来描述一下这个过程。
人生中我们会经历出生、幼儿期、儿童期、青年期、中年期、老年期、死亡这一系列的周期,同样我们经常使用的Activity 也会经历创建 ,onCreate ,onStart ,onResume ,onPause ,onStop 和onDestroy 等生命周期,走完这一短暂又精彩的一生,我们可以看到一张非常经典的Activity生命周期图 :
与人生不可逆的状态相比,Activity 可以重复很多次onStart() ,onResume() ,onPause() 和 onStop() 。如果我们把Activity 的resume 比作人最壮年的时期,那么从onCreate () -> onStart() ->onResume() 可以看作成一个状态上升;从onResume() -> onPause() -> onStop() 可以看作成状态下降,类似于下面的这张图:
首先我们需要明白的一点是,当我们的Activity 执行的某个生命周期方法,只是其生命周期中的一个时间点,而不是时间段。因此在LifeCycle 源码中,把Activity 的整个生命周期分成了7 个时间段:
- 从被创建到调用
onCreate() 之间的时间段,称之为INITIALIZED ; - 从
onCreate() 之后,到onStart() 之前的时间段,称之为CREATED ; - 从
onStart() 之后,到onResume() 之前的时间段,称之为STARTED ; Activity 调用了onResume() ,可以说是一瞬间的事件单,称之为RESUMED ;- 从
onResume() 之后,到onPause() 之前,为了节省资源和逻辑,Google也把这个状态称之为STARTED ; - 从
onPause() 之后,到onStop() 之前,同时也是为节省资源,Google也把这个状态称之为CREATED ; - 最后一种状态,从
onStop() 之后,到onDestroy() 之前,称之为DESTROYED .
为了便于运算,我们需要将5 个State 进行大小排序:
DESTROYED < INITIALIZED < CREATED < STARTED < RESUMED
理解了上述的前提知识,我们现在需要弄清楚这样一个逻辑,在ReportFragment 的各个生命周期事件中,是如何通过dispatch 不同的Event ,比如
Lifecycle.Event.ON_CREATE ,Lifecycle.Event.ON_START ,Lifecycle.Event.ON_RESUME ,Lifecycle.Event.ON_PAUSE ,Lifecycle.Event.ON_STOP ,Lifecycle.Event.ON_DESTROY
来通知注册的LifecycleObserver , 从而执行自定义LifecycleObserver 中对应的生命周期方法。 大体的意思可以参考下图:
这里就不卖关子了,直接看LifeCycle 源码怎么做了。 上面我们说过,Activity 的生命周期可以分开两部分去看,一部分是从construct到onResume() 的过程,可以理解为由弱变强的过程,上上图曲线斜率一直为正的过程;另外一个部分是由onResume()到OnDestory() 的过程,可以理解为有强变弱的过程,上上图斜率一直为负的过程。
在LifeCycle 源码中,也是按照这个想法分成两个过程的,上升和下降,它有一个很重要的方法叫getStateAfter(Event) ,位于androidx.lifecycle.LifecycleRegistry#getStateAfter() 下,大概的意思就是按照ReportFragment 分发的LifeCycle.Event , 来确定当前注册的LifecycleObserver 应该确定在什么周期范围内。
这个getStateAfter 方法的源码就不贴了,直接贴张图了解一下其意思: 对于上升趋势的LifeCycle.Event :
具体怎么理解呢? 我ReportFragment 分发的一个Lifecycle.Event.ON_CREATE 事件,这时候注册的LifecycleObserver 们的生命周期State 需要到CREATED 阶段; 同样Lifecycle.Event.ON_START 事件,LifecycleObserver 们的生命周期State 需要到STATED ; 最后分发ON_RESUME 事件,LifecycleObserver 们的生命周期的State需要到RESUME .
同理,对于下降趋势的LifeCycle.Event ,也有相应的图对应:
大致原理和上图差不多,就不细说了。
然后两张图拼接在一起:
按照上面的这张图,我再次把逻辑说一遍,也许第一次看上次会觉得比较乱,但是多体会体会,会觉得LifeCycle 的源码真的写的很艺术:
ReportFragment 会在特定的生命周期方法内分发一个LifeCycle.Event 事件,然后这个事件会在LifecycleRegistry 这个类中被转化成State 状态,然后LifecycleRegistry 会分发给注册的LifecycleObserver ,更新每一个LifecycleObserver 中指向的State 值,使得所有的LifecycleObserver#State 同步,从而达到LifecycleObserver 监听LifeCycleOwner 的生命周期的目的。
当然还有更加细节的逻辑,可能没有讲到,主要是画图我就感觉头晕脑胀了。当然,你看这个图时候,其实每条都有其特殊的意义,upEvent和downEvent不仅仅包含了LifeCycle.Event 转化为State 的逻辑,同时也包含了State 生成LifeCycle.Event 的行为。
什么意思呢? 举个例子,在upEvent的逻辑中,如果我得知当前的State 是CREATED 状态的,那么下一个事件将要指向为LifeCycle.Event.ON_START 事件。这个是干什么用的呢?不扯淡了,就是执行对应注解@OnLifecycleEvent(Lifecycle.Event.ON_START) 修饰的方法使用的,这里有时间再写篇文章聊聊这个问题吧。
对于LifeCycle 的原理,基本上也算是讲了一遍,没有非常深入的讨论源码,因为我认为每个人读源码深入程度都不一样,而且对的源码讲原理也会枯燥和无味,那么我就用自己所理解的语言写出来。当然,这也算是自己的理解,肯定会非常的粗糙和混乱,希望大家可以指出。
|