生命周期组件 Lifecycle 源码解析(二)
上篇文章中我们以继承自 AppCompactActivity 这种情况来分析 Lifecycle 的源码。本篇,我们将一起来分析下继承自普通 Activity 这种情况下的源码分析。
support library 27.0.0与 28.0.0 下使用的区别
之前说道,我们如果不继承自 AppCompactActivity ,就只能自己手动在各 Activity 的生命周期方法中调用 markState(...) 函数来进行生命周期事件的分发。类似下图:
但是如果你是用的是 27.0.0 版本的 support library ,你会发现你这样实现的话是没有效果的。
你还需要自己再手动调用 LifecycleRegistry 类的handleLifecycleEvent(...)
方法。
因为 support library 27.0.0 下引入的 Lifecycle 的 common
库的版本是 1.0.0(引入的 runtime 库会自动引入 common 等库),而 28.0.0版本引入的则是 1.1.1,二者的实现是有差别的,可以看下下面的源码。
先来看1.1.1
版本下实现:
再来看下1.0.0
版本下实现:
可以看出,在 1.0.0 版本中,markState()
方法,仅仅是对 State 进行了赋值,而没有对事件进行分发,而在 1.1.1 版本中则是在标记 State 的时候,同时进行事件的分发。这就不用我们再像之前那样写那一行繁琐的代码,还要去根据生命周期方法来判断传进去什么 Event 作为参数。
那我们本篇所讲的继承自普通 Activity 情况下的源码解析,就是这个?当然不是。如果是这个,那就没有必要再讲了,因为这些在上篇中已经讲过了。继续往下看。
引入 extensions 库之后的源码解析
虽然通过重写 Activity 生命周期,并通过在各方法中仅添加一行mLifecycleRegistry.markState()
代码就能实现生命周期的感知。但是,作为推动社会发展的“懒人” -- 程序员,自然想通过更简单的方式来解放右手。办法总比困难多。
从上一篇文章我们知道,通过继承 AppCompactActivity 这种实现方式中核心就是向 Activity 中注入一个空的 Fragment--ReportFragment。我们能不能也通过这种方式,动态的向 Activity 中注入这个 ReportFragment 呢?
我当时是这么想的。之前阅读8.1
的系统源码的时候,了解到能通过 Application
的registerActivityLifecycleCallbacks()
方法监听 Activity 的生命周期。说明这条路是可行的。
当然,我们没必要自己进行实现,因为 Google 已经帮我们实现了。Google 为我们提供了一个extensions
库,我们需要单独引入:
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
该库同时也会自动引入 LiveData 和 ViewModel 相关库,关于这二者,我们之后的文章中会另行讲解。
引入该库之后,我们的使用方式,就跟继承自 AppCompactActivity 基本相同,唯一的不同点就是我们需要自己实现 LifecycleOwner :
引入该库之后,我们Command/Ctrl+鼠标左键
,点击ReportFragment,会发现使用到它的有两个类:LifecycleDispatcher.java
和 ProcessLifecycleOwner.java
这两个类,而这二者,就是android.arch.lifecycle:extensions:1.1.0
这个库下的类:
那我们就先追踪ReportFragment.injectIfNeededIn(activity);
在LifecycleDispatcher.java
类中的调用:
ReportFragment.injectIfNeededIn(activity);
这行代码是在 LifecycleDispatcher 的静态内部类DispatcherActivityCallback
的 onActivityCreated(...) 方法中调用的。而DispatcherActivityCallback
又继承自EmptyActivityLifecycleCallbacks
,EmptyActivityLifecycleCallbacks
是啥?它其实就是Application.ActivityLifecycleCallbacks
接口的空实现类。
看到这就对上了,原来 Google 采用的就是我们前面提到的方式,通过Application.ActivityLifecycleCallbacks
进行监听。
继续回到上面的 LifecycleDispatcher
的源码查看,发现静态内部类 DispatcherActivityCallback
的实例化是在LifecycleDispatcher
类的static
方法init()
中,在该方法中进行监听器的注册:
这里面,就真正的看到了通过Application
的registerActivityLifecycleCallbacks
来注册监听器。
继续追踪 LifecycleDispatcher#init(...)
方法,就进入了ProcessLifecycleOwnerInitializer
类的onCreate()
方法:
在其 onCreate() 方法中,进行了LifecycleDispatcher 的初始化,并且也进行了ProcessLifecycleOwner 的初始化。关于ProcessLifecycleOwner ,这里我们简单点下,它也实现了 LifecycleOwner 接口,主要用来监听应用的前后台切换。
回过来继续看ProcessLifecycleOwnerInitializer
,它继承自 ContentProvider ,也就是说,它是个 ContentProvider ,但通过看源码,发现它对 ContentProvider 的各种方法都进行了空实现。其实,这里就是利用了 ContentProvider 的隐式加载。它的 onCreate() 方法执行时机是在Application 的 onCreate()方法之前。这样它就能通过 Application 来监听 Activity 的创建,并判断是否已经添加过了一个空UI的 ReportFragment。若没有,就进行添加。这种设计真的是太妙了。
我们知道,四大组件都是要在 AndroidManifest.xml 文件中进行生命的。那这个 ContentProvider 类型的 ProcessLifecycleOwnerInitializer 又是在什么时候声明的呢?
我们找到extensions
库,通过如下方式查看它的下载位置:
然后打开这里的AndroidManifest.xml
,会发现,在这里进行了声明。
这里的AndroidManifest.xml
最终会合并入我们app module
的AndroidManifest.xml
文件中。
至此,我们就对 Lifecycle 的源码进行了完全的解析。包括继承自普通 Activity 和继承自AppCompactActivity这两种情况。
补充
这里,再进行一点补充。如果我们使用的是 Java8,我们可以通过依赖下面这个库,来避免使用@OnLifecycleEvent(...)
注解的方式进行生命周期回调方法的声明:
implementation "android.arch.lifecycle:common-java8:1.1.1"
这个库其实就一个 DefaultLifecycleObserver.java
接口类。之后我们需要 LifecycleObserver 的时候,一般实现 DefaultLifecycleObserver 接口即可(不用再去直接实现 LifecycleObserver 接口),使用方式变成了下面这样:
可以看到,这里我们直接在覆写的生命周期对应回调方法中写入我们的逻辑代码即可。更加简洁。
后续文章会继续讲 LiveData 及 ViewModel 等Architecture Components,欢迎关注公众号类获取最新消息。