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的原理,基本上也算是讲了一遍,没有非常深入的讨论源码,因为我认为每个人读源码深入程度都不一样,而且对的源码讲原理也会枯燥和无味,那么我就用自己所理解的语言写出来。当然,这也算是自己的理解,肯定会非常的粗糙和混乱,希望大家可以指出。
|