前语
Lifecycle
即生命周期,作为Android开发者,咱们对生命周期可太了解了,由于咱们不只经常在Activity
、Fragment
的生命周期函数比方onCreate
、onResume
等中做一些逻辑操作;而且组件的生命周期操控不当的话,可能会导致内存走漏,或许一些无法预想的成果,比方在后台恳求网络操作的协程生命周期,要是大于所需求展现UI的界面的生命周期时,就会导致不必要资源糟蹋。
已然Activity
、Fragment
、协程、ViewModel
、LiveData
,甚至咱们常用的Handler
等一切方针,都需求严格管理生命周期,所以管理这些组件的生命周期就十分重要,这儿大约能得到2点关于生命周期的需求:
-
给
Activtiy
和Fragment
这种常用的、显现UI的组件,搞一个一致的生命周期表明规矩,这样就能够极大地便利开发者。比方咱们都希望在页面临用户可见时,才更新UI,对用户不行见时,更新UI是无用功。可是比方
Fragment
就比Activity
多了onCreateView
、onViewCreated
等几个生命周期函数,Fragment
的View
关于可见这个判别就和Activity
不相同了,这就导致开发者完结一个功用,需求对接多个组件。 -
能够获取和监控组件的一致生命周期函数改动。比方不论是
Activity
仍是Fragment
,咱们都希望在回调其onDestroy()
办法前,释放一些资源,防止形成内存走漏和资源糟蹋。
所以Lifecycle
组件就被开发出来了,面临需求对接多个组件的杂乱状况,一个有用的办法便是笼统出一层,而Lifecycle
的思维也是如此,让本来开发者需求多个组件的状况下,现在就变成了对接一个组件。
如上图所示,有了Lifecycle
后,就能够一致组件的生命周期了,这样咱们在开发时就能够面向Lifecycle
这一个组件了,这儿咱们以运用StateFlow
为例,一般是调用LifecycleOwner
(生命周期持有者)的repeatOnLifecycle
办法:
//该办法为lifecycle-runtime-ktx中办法,用于监听Satate类型的uiState的改动
public suspend fun LifecycleOwner.repeatOnLifecycle(
state: Lifecycle.State,
block: suspend CoroutineScope.() -> Unit
): Unit = lifecycle.repeatOnLifecycle(state, block)
该办法合作StateFlow
运用以抵达和运用LiveData
相同的效果,测验代码如下:
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// 当LifecycleOwner的状况在STARTED及以上时,会触发block履行
// 当ON_STOP事情产生时,block协程会被撤销
// 当LifecycleOwner接收到ON_START事情时,会从头履行block
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
uiStateFlow.collect { uiState ->
updateUi(uiState)
}
}
}
}
}
从这儿代码注释咱们能够看出,这儿其实完结了相似LiveData
的效果:会在Activity
可见时绘制UI,在Activity
毁掉时撤销协程,保证协程的生命周期可控,能够有用地节省资源和防止内存走漏。
而这个的要害办法repeatOnLifecycle
就是LifecycleOwner
的扩展函数,这儿不只仅Activity
是LifecycleOwner
,Fragment
也是完结该接口,这也便是前面所说的咱们开发新功用时只需求面临Lifecycle
这一个笼统层的组件即可。
正文
已然咱们想把生命周期给笼统出来,再结合生命周期的效果,这儿咱们就能够考虑一下,应该给笼统为几个部分。在Android中的Lifecycle
结构库中,首要触及的类如下:
classDiagram
class LifecycleOwner{
<<interface>>
---
+Lifecycle getLifecycle()
}
LifecycleOwner --> Lifecycle
class Lifecycle{
<<Abstract>>
AtomicReference<Object> mInternalScopeRef
+addObserver(@NonNull LifecycleObserver observer) void
+removeObserver(@NonNull LifecycleObserver observer)
+getCurrentState() State
}
Lifecycle ..> LifecycleObserver
class LifecycleObserver{
<<interface>>
---
}
Lifecycle ..> State
class State{
<<enum>>
DESTROYED
INITIALIZED
CREATED
STARTED
RESUMED
+isAtLeast(@NonNull State state) boolean
}
class FullLifecycleObserver{
<<interface>>
}
LifecycleObserver <|-- FullLifecycleObserver
class DefaultLifecycleObserver{
<<interface>>
}
FullLifecycleObserver <|-- DefaultLifecycleObserver
class LifecycleEventObserver{
<<interface>>
}
LifecycleObserver <|-- LifecycleEventObserver
class Activity{
+getLifecycle() Lifecycle
}
class Fragment{
+getLifecycle() Lifecycle
}
LifecycleOwner <|.. Activity
LifecycleOwner <|.. Fragment
这儿假设对UML
类图还不了解的,能够检查文章:# 功率进步 | UML类图。
从上面UML
类图咱们能够知道如下信息:
-
咱们常用的
Activity
和Fragment
都是完结了LifecycleOwner
接口,即为生命周期持有者,而LifecycleOwner
是单办法接口,咱们能够调用其getLifecycle()
办法回来一个Lifecycle
方针。 -
Lifecycle
是一个笼统类,从其界说的3个办法来剖析,首要就2个效果:- 经过添加和移除调查者的调查者模式,咱们能够监听
Lifecycle
派发的事情,调查者一致界说为LifecycleObserver
接口。 - 经过
getCurrentState()
办法,咱们能够获取当时Lifecycle
的状况,这儿的状况State
是一个枚举类型。
- 经过添加和移除调查者的调查者模式,咱们能够监听
这也印证了文章刚开端咱们笼统Lifecycle
的原意,咱们先不急着探求其原理,咱们先来考虑一下,咱们怎么运用这些供给的API
。
Lifecycle
的根本用法
第一种用法便是前面所说的,能够监听Lifecycle
所派发的生命周期事情,测验代码如下:
//Activity中代码
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(object : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
Logger.d("source = $source event = $event")
}
})
}
由于Activity
完结了LifecycleOwner
接口,所以这儿能够获取Lifecycle
方针,经过addObserver()
办法能够添加调查者,这儿的LifecycleEventObserver
为LifecycleObserver
的子接口:
classDiagram
class LifecycleObserver{
<<interface>>
---
}
class LifecycleEventObserver{
<<interface>>
+onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) void
}
LifecycleObserver <|-- LifecycleEventObserver
class Event{
<<enum>>
ON_CREATE
ON_START
ON_RESUME
ON_PAUSE
ON_STOP
ON_DESTROY
ON_ANY
}
LifecycleEventObserver ..> Event
而这儿的生命周期事情便是Event
,关于Activity
来说,其便是对应了其几个生命周期办法,所以上面测验代码中,咱们把APP页面翻开再封闭,打印如下:
第二种用法便是前面所说的能够调用getCurrentState()
办法来获取当时Lifecycle
的状况,关于状况State
总共界说了5种枚举,至于为什么是5种,咱们等会说原理时细说,这儿咱们大约和生命周期函数履行完的状况对应起来。
这儿咱们以LiveData
来举例,LiveData
是具有生命周期感知才能的调查者容器,所以有个特性:运用LiveData
为数据源,做数据驱动来更新UI时,当UI页面不行见时,是不会更新UI的。
已然和生命周期有关,那就有必要得用Lifecycle
了,下面是运用LiveData
更新UI:
//Activity中代码
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.uiState.observe(this){
updateUI(it)
}
}
这儿调用了LiveData
的observe
办法:
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer){
assertMainThread("observe");
//注释1
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
...
}
这儿咱们能够发现该办法第一个参数是LifecycleOwner
,即生命周期持有者,而咱们所了解的Activity
就完结了该接口。在注释1处,会判别Lifecycle
的当时状况,假设是DESTROYED
的话,就没必要继续操作了,即当时生命周期组件现已是毁掉状况了,彻底没必要更新UI了。
这只是LiveData
运用Lifecycle
的getCurrentState()
办法获取状况的一个运用之处,更多关于LiveData
的生命周期感知才能,咱们后边介绍LiveData
时再说。
第三种运用Lifecycle
组件的用法便是简化代码,核心思维是别离关注点,让本来需求在Activity/Fragment
的生命周期办法中写的逻辑,给整理到一个生命周期调查者中,这儿咱们运用官方比方:
class MyActivity : AppCompatActivity() {
//地理位置监听器
private lateinit var myLocationListener: MyLocationListener
override fun onCreate(...) {
//在onCreate办法中,创立监听器,依据监听器更新UI
myLocationListener = MyLocationListener(this) { location ->
// update UI
}
}
public override fun onStart() {
super.onStart()
//判别监听器是否被调用,开启服务
Util.checkUserStatus { result ->
// what if this callback is invoked AFTER activity is stopped?
if (result) {
myLocationListener.start()
}
}
}
public override fun onStop() {
super.onStop()
//及时暂停服务,防止资源糟蹋和内存走漏
myLocationListener.stop()
}
}
上述代码我信任许多开发者都写过,为了服务能正常创立、发动以及封闭,咱们有必要坚持服务的生命周期和Activity
一致,这样能够防止内存走漏和防止资源糟蹋,可是这就导致每个生命周期函数中逻辑过多,这时咱们就能够运用Lifecycle
来进行优化。
相似第一种运用办法,咱们需求监听Lifecycle
的生命周期改动事情,一同做一些处理,所以咱们自界说一个调查者,代码如下:
//承继至DefaultLifecycleObserver
internal class MyLocationListener(
private val context: Context,
private val lifecycle: Lifecycle,
private val callback: (Location) -> Unit
): DefaultLifecycleObserver {
private var enabled = false
init{
lifecycle.addObserver(this)
}
//阐明ON_START事情产生,能够看成Activity的onStart函数回调
override fun onStart(owner: LifecycleOwner) {
if (enabled) {
// connect
}
}
fun enable() {
enabled = true
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
// connect if not connected
}
}
//阐明ON_PAUSE事情产生,能够看成Activity的onStop函数回调
override fun onStop(owner: LifecycleOwner) {
// disconnect if connected
}
...
}
已然是添加调查者,所以有必要是承继至LifecycleObserver
接口,前面说了,这是一个空办法接口,第一种运用办法中,咱们是运用了LifecycleEventObserver
,这儿咱们运用DefaultLifecycleObserver
接口,承继联系如下:
classDiagram
class LifecycleObserver{
<<interface>>
---
}
class FullLifecycleObserver{
<<interface>>
---
+onCreate(LifecycleOwner owner) void
+onStart(LifecycleOwner owner) void
+onResume(LifecycleOwner owner) void
+onPause(LifecycleOwner owner) void
+onStop(LifecycleOwner owner) void
+onDestroy(LifecycleOwner owner) void
}
class DefaultLifecycleObserver{
<<class>>
---
+onCreate(LifecycleOwner owner) void
+onStart(LifecycleOwner owner) void
+onResume(LifecycleOwner owner) void
+onPause(LifecycleOwner owner) void
+onStop(LifecycleOwner owner) void
+onDestroy(LifecycleOwner owner) void
}
LifecycleObserver <|-- FullLifecycleObserver
FullLifecycleObserver <|-- DefaultLifecycleObserver
这儿的差异清楚明了,便是把Event
给细分为了这几个回调函数,一同供给了默许完结。
界说完自界说的调查者后,运用如下:
class MyActivity : AppCompatActivity() {
private lateinit var myLocationListener: MyLocationListener
override fun onCreate(...) {
//只需求在onCreate中调用即可
myLocationListener = MyLocationListener(this, lifecycle) { location ->
// update UI
}
Util.checkUserStatus { result ->
if (result) {
myLocationListener.enable()
}
}
}
}
比较于最开端的代码,咱们只需求在onCreate
这一个生命周期函数中进行初始化即可,能够免除在多个生命周期函数中写逻辑,能够简化代码。
第四种用法首要是防备内存走漏,在代码规划中,有个十分重要的原则是架构和事务别离,就比方咱们常见的网络传输协议,TCP现已供给了可靠交给,就不需求咱们在事务运用层里边再写关于可靠交给的逻辑了。
在整个Jetpack
组件都是遵循这种原则的,比方咱们文章最开端的比方,repeatOnLifecycle()
办法中收集数据的协程,就会当Lifecycle
处于DESTROYED
时主动撤销,这样就把适宜机遇撤销协程,防止资源糟蹋和内存走漏这个架构规划和事务逻辑给分开了,而不必咱们在事务处理时,还考虑这些。
除此之外,还有十分多的小比方,比方这儿防止内存走漏的Handler
:
//这儿承继Handler,完结LifecycleEventObserver接口
class LifecycleHandler(val lifecycleOwner: LifecycleOwner) : Handler(),
LifecycleEventObserver {
init {
addObserver()
}
private fun addObserver() {
lifecycleOwner.lifecycle.addObserver(this)
}
//当生命周期持有者状况为DESTROYED时,移除一切音讯和回调,保证能够正常被GC收回
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
if (event == Lifecycle.Event.ON_DESTROY) {
removeCallbacksAndMessages(null)
lifecycleOwner.lifecycle.removeObserver(this)
}
}
}
由于Activity
和Fragment
都是完结了LifecycleOwner
接口,所以一切依靠Activity
和Fragment
的类,都能够采取相似战略,比方Dialog
等,将内存走漏消除在架构层逻辑。
看到这儿,我信任你会有一些疑问。比方DefaultLifecycleObserver
中的onCreate()
回调是怎么和Activity
中的onCreate()
回调坚持联动的?有没有先后调用顺?换成Fragment
为生命周期持有者,会不会有什么改动?
带着这些疑问,咱们来剖析一下其源码。
Lifecycle
解析
已然Lifecycle
是生命周期的笼统,首要用于获取当时生命周期状况以及派产生命周期事情,那么Activity
和Fragment
的生命周期函数个数是不相同的,所以这儿需求界说一个愈加通用的笼统层。
按照规划,表明Lifecycle
的状况是State
类,它总共有5种状况;而表明状况切换的事情,总共有7个,这儿了解起来比较要害,官方有一个图如下:
这儿咱们以Activity
为例,来解释一下这几种State
意义:
-
依据枚举界说,每个枚举值都有一个
int
类型ordinal
值,表明界说枚举的次序,这个值默许便是0到4
,即State.DESTROYED
最小,State.RESUMED
最大,这也便是状况高低的说法,也是isAtLeast()
办法履行的依据://State的办法 public boolean isAtLeast(@NonNull State state) { return compareTo(state) >= 0; }
比方调用
isAtLeast(STARTED)
为true
,就阐明当时Lifecycle
状况为STARTED
或许RESUMED
。 -
咱们所熟知的
Activity
的生命周期函数如图:
这儿不算onRestart()
办法总共有6个,可是在前面咱们界说的Lifecycle
中State
却没有这么多,所以这儿要留意,这儿的State
更多的表明是一种状况,而非和生命周期函数一一对应。
- 这儿对每一种
State
做详尽讲解:-
DESTROYED
:它是最小状况,表明现已毁掉的状况,在这个状况的Lifecycle
将不再分发任何生命周期事情Event
,这个状况在Activity
的onDestroy()
调用前抵达。 -
INITIALIZED
:表明初始化状况,表明Activity
现已被创立,可是还没有回调onCreate()
办法,即在onCreate()
办法回调前的状况是该状况。 -
CREATED
:表明已创立的状况,留意这种状况不只仅在Activity
的onCreate()
办法回调后抵达,而且在onStop
回调前也是属于该状况,简略来说便是处于CREATED
状况时,组件现已被创立,可是不行见且不行交互。 -
STARTED
:表明可见状况,可是无法交互,所以这种状况在onStart()
回调后和onPause()
回调前抵达。 -
RESUMED
:表明处于可交互的running
状况,这也只有在onResumd()
回调后抵达。
-
上面咱们以Activity
生命周期为例,剖析了各种State
的效果,能够总结为下图:
这儿咱们能够知道一个完好的Activity
生命周期,其State
状况是从小到大,再到小,这也是契合咱们笼统生命周期的理念:咱们更偏重想知道当时Lifecycle
的状况,比方是否可见,是否现已被毁掉,便利对应逻辑操作,而生命周期改动的事情,由Event
来界说和派发。
说完了State
,咱们来看看其向调查者所派发的Event
事情,这儿搞清楚一个规划思路:Lifecycle
的状况切换是由Event
所导致,所以能够以为State
便是一个图中的节点,而Event
便是衔接节点的边。
前面咱们是以Activity
来阐明State
的,其实真实的Event
规划的差不多,也是对应着几种回调函数来规划的,Event
是枚举类,共有6种事情,以及一系列状况切换办法,咱们举个简略比方来阐明Event
工作流程:
sequenceDiagram
Activity ->> Observer:注册调查者
Activity -->> Activity:onCreate()回调
Activity ->> Observer:派发ON_CREATE事情
Observer -->> Observer:逻辑处理
所以Event
的界说共如下几种:ON_CREATE、ON_START、ON_RESUME、ON_PAUSE、ON_STOP和ON_DESTROY,至于各自的意义,这儿不多说了,便是和生命周期回调函数对应。
这儿有个难点,便是Event
中界说的几个办法,合作State
运用,咱们来剖析一下。
downFrom
办法界说如下:
public static Event downFrom(@NonNull State state) {
switch (state) {
case CREATED:
return ON_DESTROY;
case STARTED:
return ON_STOP;
case RESUMED:
return ON_PAUSE;
default:
return null;
}
}
解释:当从参数state
离开往更低的状况切换,需求分发的Event
。这儿的downFrom
函数名咱们要分开看,其间down
表明动词,表明向下,而from
便是阐明从哪个状况开端,这儿结合前面的状况图一同,看代码完结:
- 咱们从
CREATED
状况开端,向下降低状况,依据状况图,它下一个状况便是DESTROY
,需求派发ON_DESTROY
事情来完结状况切换。
- 咱们从
STARTED
状况开端,向下降低状况,依据状况图,它的下一个状况是CREATED
,需求派发ON_STOP
事情来完结状况切换。
相似的办法还有downTo
:
public static Event downTo(@NonNull State state) {
switch (state) {
case DESTROYED:
return ON_DESTROY;
case CREATED:
return ON_STOP;
case STARTED:
return ON_PAUSE;
default:
return null;
}
}
其间down
是动词表明向下,to
表明希望抵达某个状况,这儿咱们需求留意一点:不论是down
,仍是后边要说的up
,状况改动只能一步一步来。
即我想从RESUMED
状况,下降到CREATED
状况,依据状况图有必要先下降到STARTED
状况,再下降到CREATED
状况,所以咱们再看前面downTo
的完结,当希望下降的状况是DESTROYED
时,依据一次只能下降一步的原则,其实它的上一个状况便是CREATED
,所以需求派发ON_DESTROY
事情来完结状况切换。
这儿还有相似的upFrom()
和upTo()
办法,咱们就不剖析了,可是咱们要了解其规划思路:这些办法有什么用?
不论是down
仍是up
,它的意图都是改动状况State
的值,那我直接改动其值不就好了吗?为什么要知道每一步改动的事情呢?
这就触及一个思维:永久是事情驱动状况改动,即事情导致状况改动。这儿表现为2个方面:
- 关于
Activity
这种生命周期持有者来说,永久都是其自己的onCreate()
办法回调后,收到了ON_CREATE
事情,其状况才改动为CREATED
状况。 - 关于新添加的调查者来说,调查者默许状况是初始化状况,这时假设被调查者现已是
RESUMED
状况,这时需求进步新添加的调查者的状况,从INITIALIZED
进步到RESUMED
,在这个进程中,需求一步一步派发Event
,直到进步到RESUMED
状况。
这2个方面第一个十分好了解,咱们来看第二点,第二点其实就对应着Lifecycle
的2个重要函数:addObserver
和removeObserver
。
这儿暂时还没有到剖析原理的当地,咱们能够先说定论,等后边剖析原理时再验证一下:
- 关于
addObserver
办法,它是添加一个调查者,当被调查者的状况产生改动时,会告诉调查者。
被添加的调查者状况,会被进步到和被调查者相同的状况。比方
LifecycleOwner
的状况是STARTED
,这个刚被添加的调查者,就需求派发ON_CREATE
和ON_START
事情。
- 关于
removeObserver
办法,它是移除一个调查者。
到这儿咱们只是在接口层剖析了Lifecycle
的运用,那么接下来便是重点工作了,咱们来剖析一下Lifecycle
是怎么对Activity
和Fragment
进行笼统和封装的。
Lifecycle
原了解析
从前面接口和运用剖析,咱们知道Lifecycle
是调查者模式,能够用来获取当时Lifecycle
的State
,以及经过调查者来监听Lifecycle
所派发的Event
。
所以这儿咱们需要知道Lifecycle
是怎么进行笼统的,是怎么添加/移除调查者,以及怎么派发Event
,即
这一部分的工作原理,咱们先以Activity
为例来解析源码。
话不多说,咱们仍是先来看看相关类的联系:
classDiagram
ViewModelStoreOwner <|.. ComponentActivity
LifecycleOwner <|.. ComponentActivity
ComponentActivity <|-- FragmentActivity
FragmentActivity <|-- AppCompatActivity
class ComponentActivity{
-LifecycleRegistry mLifecycleRegistry
+getLifecycle() Lifeycle
}
ComponentActivity --> LifecycleRegistry
Lifecycle <|-- LifecycleRegistry
class Lifecycle{
<<Abstract>>
AtomicReference<Object> mInternalScopeRef
+addObserver(@NonNull LifecycleObserver observer) void
+removeObserver(@NonNull LifecycleObserver observer)
+getCurrentState() State
}
class LifecycleRegistry{
-State mState
-FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap
-WeakReference<LifecycleOwner> mLifecycleOwner
+handleLifecycleEvent(@NonNull Lifecycle.Event event) void
+addObserver(@NonNull LifecycleObserver observer) void
+removeObserver(@NonNull LifecycleObserver observer) void
+getCurrentState() State
}
AppCompatActivity <|-- MainActivity
这儿咱们能够发现ComponentActivity
完结了LifecycleOwner
接口,即咱们平常运用Activity
便是生命周期持有者。
咱们调用getLifecycle()
办法时,其实便是回来ComponentActivity
中界说的LifecycleRegistry
类型的mLifecycleRegistry
成员变量:
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
而且LifecycleRegistry
完结了Lifecycle
接口,所以这儿运用了署理模式,一切操作都由这个LifecycleRegistry
来完结。
咱们先不去看其源码,咱们先来剖析一下Activity
生命周期事情是什么时分派发给LifecycleRegistry
的。
本来我以为分产生命周期事情,会在ComponentActivity
的各个生命周期回调函数中调用LifecycleRegistry
办法来派发事情,看了源码发现是运用了ReportFragment
来完结的,调用联系如下:
sequenceDiagram
ComponentActivity ->> LifecycleRegistry: 持有变量
Note right of LifecycleRegistry:INITIALIZED
LifecycleRegistry ->> Observer:注册调查者
ComponentActivity ->> ComponentActivity:onCreate()
ComponentActivity ->> ReportFragment:injectIfNeededIn(this)
ComponentActivity -->> ReportFragment:更新依靠的Fragment生命周期
ReportFragment ->> ReportFragment:onActivityCreated()
ReportFragment ->> ReportFragment:dispatch(Event.ON_CREATE)
ReportFragment ->> ReportFragment:dispatch(getActivity(), Event.ON_CREATE)
ReportFragment ->> LifecycleRegistry:handleLifecycleEvent(Event.ON_CREATE)
Note right of LifecycleRegistry:CREATED
LifecycleRegistry ->> Observer:notify()
上面黄色的Note
表明Lifecycle
的当时State
,由这儿咱们能够验证最开端说的State
意义:其间INITIALIZED
初始化状况表明组件现已被创立,可是没有收到ON_CREATE
事情,当收到ON_CREATE
事情,状况切换到CREATED
状况。
这儿为什么能够运用ReportFragment
的生命周期回调函数中来分发Activity
的生命周期Event
呢?这就触及了Activity
和Fragment
生命周期函数的调用联系,如下图:
尽管这儿Fragment
比Activity
多几个生命周期函数,可是一点点不影响咱们运用Fragment
的生命周期来派发其所依靠的Activity
的生命周期事情。
经过简略检查源码,对应联系如下:
-
Activity
的ON_CREATE
事情在Fragment
中的onActivityCreated()
办法中分发。 -
ON_START
、ON_RESUME
、ON_PAUSE
、ON_STOP
和ON_DESTROY
都是由其同名生命周期办法中分发。
这儿分发事情的办法便是调用LifeycleRegistry
的handleLifeEvent()
办法,该办法咱们后边细说。
说完了Activity
是怎么适配Lifecycle
的,首要便是能够正确地、合理地派发Event
给LifecycleRegistry
,咱们接着来看一下Fragment
的流程,由于Fragment
有一点不相同,它在派发Event
有2套逻辑。
咱们一般运用LiveData
作为调查者容器,在Fragment
的onViewCreated()
办法中进行数据调查和更新UI:
这儿咱们运用this
即Fragment
方针作为LifecycleOwner
居然会报错,提示运用viewLifecycleOwner
作为生命周期持有者,那这儿这2个生命周期持有者有什么差异呢?假设强行运用this
会有什么问题呢?
带着问题看源码,就有了探求思路,首要便是Fragment
它是完结了LifecycleOwner
接口的,相关类如下:
classDiagram
ViewModelStoreOwner <|.. Fragment
LifecycleOwner <|.. Fragment
Fragment <|-- BusinessFragment
class Fragment{
+LifecycleRegistry mLifecycleRegistry
+getLifecycle() Lifecycle
}
Lifecycle <|-- LifecycleRegistry
class Lifecycle{
<<Abstract>>
AtomicReference<Object> mInternalScopeRef
+addObserver(@NonNull LifecycleObserver observer) void
+removeObserver(@NonNull LifecycleObserver observer)
+getCurrentState() State
}
class LifecycleRegistry{
-State mState
-FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap
-WeakReference<LifecycleOwner> mLifecycleOwner
+handleLifecycleEvent(@NonNull Lifecycle.Event event) void
+addObserver(@NonNull LifecycleObserver observer) void
+removeObserver(@NonNull LifecycleObserver observer) void
+getCurrentState() State
}
Fragment --> LifecycleRegistry
和Activity
相同,经过getLifecycle
获取的仍旧是LifecycleRegistry
实例,工作机制相同,当Fragment
的生命周期改动时,经过调用handleLifeEvent()
来保存和处理事情,咱们只需求知道在什么时分会派发事情即可,下面是源码总结:
调用链 | 派发的Event
|
Lifecycle 状况 |
---|---|---|
Fragment() 结构函数 -> initLifecycle() 创立LifecycleRegistry 实例 |
无 | INITIALIZED |
performCreate() -> onCreate() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
|
Lifecycle.Event.ON_CREATE |
CREATED |
performStart() -> onStart() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
|
Lifecycle.Event.ON_START |
STARTED |
performResume() -> onResume() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
Lifecycle.Event.ON_RESUME |
RESUMED |
performPause() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE) -> onPause()
|
Lifecycle.Event.ON_PAUSE |
STARTED |
performStop() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP) -> onStop()
|
Lifecycle.Event.ON_STOP |
CREATED |
performDestroy() -> mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY) -> onDestroy()
|
Lifecycle.Event.ON_DESTROY |
DESTROYED |
上面的代码调用流程再合作文章刚开端说的图,是不是能够完美契合上了!尤其是派发事情和生命周期回调函数的先后问题。
从这儿的生命周期回调来看,咱们能够得出定论:getLifecycle()
获取的Lifecycle
,其代表Fragment
的生命周期。
那getViewLifecycleOwner()
获取的Lifecycle
有什么差异呢?话不多说,直接看源码,触及的相关类:
classDiagram
Fragment <|-- BusinessFragment
class BusinessFragment{
+getViewLifecycleOwner() LifecycleOwner
}
class Fragment{
+FragmentViewLifecycleOwner mViewLifecycleOwner
+getViewLifecycleOwner() LifecycleOwner
}
Fragment --> FragmentViewLifecycleOwner
class FragmentViewLifecycleOwner{
-LifecycleRegistry mLifecycleRegistry
+handleLifecycleEvent(@NonNull Lifecycle.Event event) void
}
FragmentViewLifecycleOwner --> LifecycleRegistry
class LifecycleRegistry{
+handleLifecycleEvent(@NonNull Lifecycle.Event event) void
}
Lifecycle <|-- LifecycleRegistry
class SavedStateRegistryOwner{
<<interface>>
+getSavedStateRegistry() SavedStateRegistry
}
LifecycleOwner <|-- SavedStateRegistryOwner
SavedStateRegistryOwner <|-- FragmentViewLifecycleOwner
ViewModelStoreOwner <|-- FragmentViewLifecycleOwner
能够发现这儿运用了署理模式,可是署理的是LifecycleOwner
对象,所以这儿的核心代码便是FragmentViewLifecycleOwner
的完结,在这儿面咱们仍旧仍是运用LifecycleRegstry
来管理和处理Event
,所以咱们的要害仍是看看在什么时分调用了Event
,总结如下:
调用链 | 派发的Evnet
|
viewLifecycle 状况 |
---|---|---|
performCreateView() -> FragmentViewLifecycleOwner(this, getViewModelStore()) 调用结构函数 -> onCreateView() -> mViewLifecycleOwner.initialize()
|
无 | INITIALIZED |
restoreViewState() -> onViewStateRestored(savedInstanceState) -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
|
Lifecycle.Event.ON_CREATE |
CREATED |
performStart() -> onStart() -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START)
|
Lifecycle.Event.ON_START |
STARTED |
performResume() -> onResume() -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
Lifecycle.Event.ON_RESUME |
RESUMED |
performPause() -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE) -> onPause()
|
Lifecycle.Event.ON_PAUSE |
STARTED |
performStop() -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP) -> onStop()
|
Lifecycle.Event.ON_STOP |
CREATED |
performDestroyView() -> mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY) -> onDestroyView()
|
Lifecycle.Event.ON_DESTROY) |
DESTROYED |
从这儿的调用链和前面Fragment
自己的Lifecycle
做比较,咱们能够明显发现ON_START
、ON_RESUME
、ON_PAUSE
和ON_STOP
事情的派发机遇和Fragment
自己的Lifecycle
是相同的。
而其他几个Event
的派发就和Fragment
的View
的联系愈加亲近了,这儿也就阐明一件事:Fragment
的生命周期和其View
的生命周期是不相同的,getViewLifecycleOwner()
回来的viewLifecycleOwner
,表明的是Fragment
中View
的生命周期。
至于差异,咱们能够看一张官方的图:
从这张图咱们能够得出以下定论:
View
的Lifecycle
比Fragment
的Lifecycle
要短。- 当
Fragment
的Lifecycle
为CREATED
时,View
的Lifecycle
可能还没有创立,即使创立了,也会在View
创立完结后才处于CREATED
状况。 - 当
Fragment
还处于CREATED
状况时,就会调用onDestroyView()
函数,这时View
的Lifecycle
就处于DESTROYED
状况了。
剖析完上面定论,咱们就能够解决这个问题了:
为什么这儿要运用View
的Lifecycle
而不是挑选Fragment
的Lifecycle
。
原因十分简略,也便是咱们希望更新UI是依据Fragment
的View
的生命周期来做处理,而不是Fragment
的生命周期,那假设用错了,会导致什么问题呢?
这儿触及LiveData
一个特性:当LifecycleOwner
的Lifecycle
处于DESTROYED
状况时,会主动remove
该LiveData
调查者。
所以这儿的uiData
会在owner
处于DESTROYED
时主动移除监听,能够防止内存走漏,而且只更新可见的有用的UI信息。
这儿出问题的场景便是Fragment
切换时,能够把旧FragmentA
加入到回退栈中,而且翻开新FragmentB
,这时FragmentA
会履行onDestroyView()
办法,可是不会履行onDestroy()
办法,这时由于Fragment
并没有被毁掉;
这儿假设运用Fragment
的作为LifecycleOwner
,FragmentA
就不会移除uiData
这个调查者,由于它没有到DESTROYED
状况;这时再按回来键,FragmentB
出栈,FragmentA
又从头显现出来,这时会从头回调onViewCreated()
办法,又会从头添加一遍uiData
这个调查者,导致重复添加调查者。
可是运用viewLifecycleOwner
就不会呈现这种状况,依据前面生命周期图可知,当履行到onDestroyView()
办法时,Lifecycle
就处于DESTROYED
状况了,这时能够正常移除调查者。
LifecycleRegistry
原了解析
看了前面的运用以及解析,我信任你必定刻不容缓地想对LifecycleRegistry
进行探求了,看看官方是怎么完结一个Lifecycle
的。
这儿有关LifecycleRegistry
内容比较多,我一向坚持一个看源码便是一个继续学习的心态,所以这一节的内容,会比较发散,哪里不懂就探个终究,不感兴趣的能够疏忽,不影响Lifecycle
的全体学习。
仍是回忆一下LifecycleRegistry
的承继联系以及首要功用函数:
classDiagram
Lifecycle <|-- LifecycleRegistry
class Lifecycle{
<<Abstract>>
AtomicReference<Object> mInternalScopeRef
+addObserver(@NonNull LifecycleObserver observer) void
+removeObserver(@NonNull LifecycleObserver observer)
+getCurrentState() State
}
class LifecycleRegistry{
-State mState
-FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap
-WeakReference<LifecycleOwner> mLifecycleOwner
+handleLifecycleEvent(@NonNull Lifecycle.Event event) void
+addObserver(@NonNull LifecycleObserver observer) void
+removeObserver(@NonNull LifecycleObserver observer) void
+getCurrentState() State
}
LifecycleRegistry
作为Lifecycle
接口的完结类,能够处理多个调查者,依据接口界说,它有3方面效果:
-
mState
特色代表的当时Lifecycle
的状况,能够运用getCurrentState()
办法来获取状况。 - 经过调查者模型,运用
addObserver()
和removeObserver()
办法来添加和移除调查者,以及处理其间的逻辑。最首要的事务逻辑便是对调查者派产生命周期事情。 - 经过
handleLifecycleEvent()
办法来对接Activity
、Fragment
等UI组件,这个在前面咱们说过了,这些组件都是经过该办法来设置Lifecycle
的状况。
先来看一下结构函数:
代码段1
//对外的结构函数
public LifecycleRegistry(@NonNull LifecycleOwner provider) {
this(provider, true);
}
//私有结构函数
private LifecycleRegistry(@NonNull LifecycleOwner provider, boolean enforceMainThread) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
mEnforceMainThread = enforceMainThread;
}
//生命周期持有者,弱引证封装
private final WeakReference<LifecycleOwner> mLifecycleOwner;
private State mState;
//是否强制主线程
private final boolean mEnforceMainThread;
这儿有个值得学习的点,便是这儿把传递进来的LifecycleOwner
用弱引封装起来,即这儿的mLifecycleOwner
方针,当运用时需求调用mLifecycleOwner.get()
能够获取LifecycleOwner
方针。
这儿为什么要运用弱引证呢?由前面可知,这儿的生命周期持有者一般都是Activity
、Fragment
这种重量级的组件类,假设咱们经过getLifecycle()
获取的Lifecycle
产生了内存走漏,运用弱引证将不会走漏整个Activity
和Fragment
。
这儿扩展一下:什么是内存走漏,便是这个类该被GC收回了,发现还被引证则无法被收回,导致内存走漏。就比方获取的lifecycle
方针,被过错地传递给了一个全局变量,这时Activity
页面封闭,需求被收回,会发现这儿Activity
是弱引证,仍旧能够被GC收回。
弱引证效果:当一个类只被弱引证引证时,它也是能够被GC收回的。这个点仍是比较值得咱们平常学习的,防患于未然,假设引证到这种重量级的组件类,能够恰当考虑运用弱引证,以防止内存走漏。
然后便是处理Event
的handleLifecycleEvent()
办法:
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState());
}
这儿有个值得学习的点,便是怎么判别当时线程是主线程,由于不只仅这个办法,还包含添加/删去调查者都要求在主线程,咱们来看一下:
private void enforceMainThreadIfNeeded(String methodName) {
if (mEnforceMainThread) {
if (!ArchTaskExecutor.getInstance().isMainThread()) {
throw new IllegalStateException("Method " + methodName + " must be called on the "
+ "main thread");
}
}
}
@Override
public boolean isMainThread() {
return Looper.getMainLooper().getThread() == Thread.currentThread();
}
能够发现这儿是运用Looper
来完结的,获取主线程Looper
中的线程信息,是否等于当时线程,关于主线程Looper
是何时创立和保存线程信息的,等后边有机会介绍Looper
时再说。
咱们继续事务剖析,这一行代码moveToState(event.getTargetState())
中的getTargetState()
办法便是获取当时event
希望的状况,这儿合作源码和前面所说的State
与Event
联系图十分好了解:
//Event的办法,获取当时event后的状况
public State getTargetState() {
switch (this) {
case ON_CREATE:
case ON_STOP:
return State.CREATED;
case ON_START:
case ON_PAUSE:
return State.STARTED;
case ON_RESUME:
return State.RESUMED;
case ON_DESTROY:
return State.DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException(this + " has no target state");
}
比方Activity
派发了ON_CREATE
事情给Lifecycle
,依据逻辑,当时Lifecycle
的希望状况便是CREATED
,然后便是moveToState()
办法:
代码段2
//切换Lifecycle到next状况
private void moveToState(State next) {
if (mState == next) {
return;
}
//依据上图可知,状况是无法一次从`INITIALIZED`下降到`DESTROYED`
if (mState == INITIALIZED && next == DESTROYED) {
throw new IllegalStateException("no event down from " + mState);
}
mState = next;
//当正在处理Event或许正在添加调查者时,直接return
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
return;
}
//处理Event的进程
mHandlingEvent = true;
sync();
mHandlingEvent = false;
//当状况处于DESTROYED时,清空调查者集和
if (mState == DESTROYED) {
mObserverMap = new FastSafeIterableMap<>();
}
}
//是否正在处理事情,即履行`sync()`办法期间
private boolean mHandlingEvent = false;
//是否有新的事情产生
private boolean mNewEventOccurred = false;
//正在添加的调查者有几个
private int mAddingObserverCounter = 0;
这儿代码的flag
比较多,其实在日常开发中,为了可读性,代码仍是需求尽量少的运用flag
。这儿为什么要运用这么多flag
呢?
其实本源便是处理Event
的办法和添加/移除调查者都是在主线程上履行的,需求加快履行功率。首要便是一个Lifecycle
能够添加多个调查者,由代码可知这些调查者在封装后保存在mObserverMap
这个集和中,然后每逢Lifecycle
的状况产生改动时,需求告诉这些调查者,这些调查者再去派发事情。
而这个进程,便是上面的sync()
办法,即表明处理Event
进程,这儿的mHandingEvent
便是表明是否在这个进程,咱们来看一下该办法:
代码段3
//同步进程,即处理Event的进程
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
//生命周期持有者可能被收回了
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
//当没有同步完结时
while (!isSynced()) {
//进行一次同步
//由于mState是全局变量,假设有新的Event要处理,这时阐明现已在处理了,
//所以mNewEventOccourred置为false
mNewEventOccurred = false;
//当时状况小于链表最大值,需求降低状况
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
//当时状况大于链表最小值,进行前进进步处理
Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
//是否是希望的同步完状况
private boolean isSynced() {
if (mObserverMap.size() == 0) {
return true;
}
//最老调查者的状况
State eldestObserverState = mObserverMap.eldest().getValue().mState;
//最新调查者状况
State newestObserverState = mObserverMap.newest().getValue().mState;
//最老最新状况相同且Lifecycle当时状况等于最新状况
return eldestObserverState == newestObserverState && mState == newestObserverState;
}
//保存调查者的集和
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
上面信息比较多,首要效果便是同步一切调查者的状况,这个什么意思呢?
假设当时Lifecycle
有4个调查者,以链表形式保存,每个调查者状况分别为1 -> 1 -> 1 -> 1
,依据枚举值,这儿的1
便是INITIALIZED
状况,这时Lifecycle
收到了ON_CREATE
事情,依据切换图,这时Lifecycle
为CREATED
状况,这时就需求同步4个调查者的状况,告诉调查者的回调函数,需求派发ON_CREATE
事情,即把状况变为2 -> 2 -> 2 ->2
这样,就算是同步完结。
这儿需求再补充一下保存调查者的集和mObserverMap
,这个集和比较特殊,后边详细学习介绍一下,这儿大约说一下,FastSafeIterableMap
便是一个简易版的LinkedHashMap
,能够在遍历时添加和删去,保存着调查者,可是它有一个不变的特性:在任何时分,关于Observer1
和Observer2
来说,假设被Observer1
的添加次序小于Observer2
的添加次序,那么Observer1
的状况要大于等Observer2
。
这个特性说人话便是这个mObserverMap
尽管是个Map
,可是添加的Observer
是有次序的,任何时分,早添加的值都不小于晚添加的,即这是一个非递加链表。
假设有3个调查者,其状况可能是3 -> 2 -> 2
,或许3 -> 2 -> 1
,绝对不会是2 -> 3 -> 2
这种状况。
简略了解完mObserverMap
的保存特性后,再来剖析上面同步进程,假设现在有3个调查者,状况分别为2 -> 2 -> 1
,这时Lifecycle
收到ON_START
事情,mState
切换为STARTED
,这时需求同步3个调查者状况,依据前面代码段3中判别:当时Lifecycle
的mState
为3,3比链表最大值2要大,不会履行backwardPass()
办法;一同3又比链表最小值1要大,所以需求履行forwardPass()
办法:
代码段4
private void forwardPass(LifecycleOwner lifecycleOwner) {
//获取一个升序遍历迭代器
Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
//当没有遍历完,且没有新的Event产生
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
//当时节点
Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
//当时节点的值
ObserverWithState observer = entry.getValue();
//当时节点状况低于mState的状况
//没有新的Event需求派发
//当时节点还没有被删去
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
//暂时疏忽
pushParentState(observer.mState);
//进步一级状况,需求派发的Event
final Event event = Event.upFrom(observer.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + observer.mState);
}
//告诉调查者派发Event
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
在了解完mObserverMap
的非递加特性后,再来看看这段逻辑就十分好了解了,即forward
(进步)一切调查者的状况,这儿运用的是升序遍历迭代器,即从大到小进行进步状况,即使被中断了,履行到一半的行列也是契合非递加特性的。每一个调查者自己也需求一个状况,这个待会在添加调查者时细说。
在代码完结中,咱们能够看见有2层while
循环,也就阐明这是一个比较耗时的操作,而这也就表现了mNewEventOccurred
和mHandingEvent
的效果了。
咱们来举个比方,假设现有的调查者状况为2,2,1
,这时handleLifecycleEvent
收到了ON_START
事情,这时mState
变为3,希望调查者行列同步为3,3,3
,此时就需求履行这个耗时的forwardPass()
办法,在这期间,mHandingEvent
为true
。假设这时刚同步到3,2,1
状况,又收到了ON_RESUME
事情,这时代码段2又被履行了,mState
变为4,可是由于前一个同步还没有完结,这时mNewEventOccurred
就变成了true
,这时forwardPass()
会停止履行,回到代码段3中的while
循环,从头设置希望的行列为4,4,4
,然后再履行forwardPass()
办法,依据2层while
遍历,把3,2,1
进步到4,4,4
。
由于都是主线程,所以这儿也没有线程安全问题,经过2个变量操控,让本来需求履行屡次的办法,能够就履行一次完结逻辑完结,大大地减缓主线程的压力。
与forwardPass()
对应的办法是backwordPass()
办法,从这儿咱们就能够反推出为什么Event
中需求规划比方downFrom()
、downTo()
等办法了。
从代码段4中的2个while
循环,咱们也能够验证一个定论,便是状况进步和下降都是一步一步履行,是经过事情驱动,即一个调查者状况从CREATED
进步到RESUMED
,就有必要要派发ON_START
和ON_RESUME
这2个事情。
咱们继续来看事务逻辑流程,说完了处理Lifecycle
的Event
,来看看怎么添加调查者Observer
,以及派发Event
。
代码段5
public void addObserver(@NonNull LifecycleObserver observer) {
//强制在主线程
enforceMainThreadIfNeeded("addObserver");
//被添加的调查者初始状况
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//带状况的调查者,把observer进行封装
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
//是否现已被添加过,留意这儿插入Map中的key是observer,value是statefulObserver
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
return;
}
//是否从头进入该办法操作,是否重复,即正在添加调查者或许正在处理Event
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
//核算新添加的observer的希望方针State
State targetState = calculateTargetState(observer);
//正在添加的Observer个数加1
mAddingObserverCounter++;
//由于初始状况是INITIALIZED,所以只需求进步到方针状况即可
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
//暂时不论
pushParentState(statefulObserver.mState);
//进步状况
final Event event = Event.upFrom(statefulObserver.mState);
if (event == null) {
throw new IllegalStateException("no event up from " + statefulObserver.mState);
}
//调查者需求派发事情
statefulObserver.dispatchEvent(lifecycleOwner, event);
popParentState();
//再次核算希望方针State
targetState = calculateTargetState(observer);
}
//在非重复状况下,进行同步
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
//进行减1
mAddingObserverCounter--;
}
//核算一个observer的希望方针State
private State calculateTargetState(LifecycleObserver observer) {
//获取该observer链表的前一个节点
Map.Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
//前一个节点的状况
State siblingState = previous != null ? previous.getValue().mState : null;
//获取parentState状况
State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
: null;
//回来最小者
return min(min(mState, siblingState), parentState);
}
addObserver
流程比较杂乱,细节较多,咱们先剖析主体事务流程:
-
首要便是对添加的
observer
进行封装为ObserverWithState
,即把状况和observer
封装到一同,正常状况下,状况是初始状况。 -
然后添加到
mObserverMap
中,这儿的插入时key
是observer
,value
是ObserverWithState
。 -
isReentrance
表明是否重入,这代表什么意思呢?这儿又触及主线程的处理Event
和添加调查者操作是否重复,比方刚调用addObserver()
办法,还没有履行完,又调用,这时mAddingObserverCounter
就不为0,表明添加调查者的操作重复了。再比方调用
addObserver()
时,Lifecycle
正在处理事情,这也是阐明2个操作之间重复了。这能够看出在这2种状况下,是不会调用sync()
办法的。 -
sync()
办法是同步一切调查者状况和mState
一致以及分发Event
,结合这儿的isReentrance
和代码段2中的判别条件,咱们能够得出如下定论:- 先履行
Event
处理,没处理完,这时再履行Event
处理,操作重复,会直接return
掉,前面说了,能够进步履行功率。 - 先履行
Event
处理,没处理完,再履行添加调查者,操作重复,判别为重复操作,在进步完新添加的调查者状况后,addObserver()
不会进行sync()
同步,由于处理Event
办法正在同步。 - 先履行添加调查者,在进步状况时,再履行
Event
处理,在添加调查者办法中,是不重复操作的,这时能够履行sync()
,可是在moveToState()
中,mAddingObserverCounter
不为空,不会进行重复履行。
说了这么多,仍是那句话,便是为了让
sync()
这个办法少履行,以进步主线程履行功率,一同防止同步状况派发事情和添加调查者操作堆叠导致问题。 - 先履行
-
关于新添加的
observer
需求核算其希望的方针状况,由于链表对错递减的,所以在插入到链表尾后,其方针状况便是前一个节点的状况。比方本来链表是
3,3
,添加进来的原始为1,即为3,3,1
,这时经过calculateTargetState()
中的ceil()
办法就能够得到其希望值为3。这儿这种逻辑十分合理,可是为什么
calculateTargetState()
办法还触及了mParentState
变量呢?这是一个及其细微的细节,这儿要考虑下面这种极点状况:
//这是一个调查者,当派发`ON_START`事情时,会触发该回调办法 void onStart(){ mRegistry.removeObserver(this) mRegistry.add(newObserver) }
首要这段代码是在一个
Observer
中写的,且当时Lifecycle
中只有this
这一个调查者,依据前面咱们所梳理的Lifecycle
处理Event
流程,当this
这个调查者履行onStart()
办法时(还没有履行removeObserver
),阐明正在派发ON_START
事情,这时Lifecycle
的mState
为STARTED
状况,调查者行列应该是CREATED -> NULL
状况,这是由于在分发Event
中,会先回调办法,再改动链表中Observer
的状况,代码履行的当地应该是代码段4中的forwardPass()
函数部分,即同步状况和派发事情。当履行完
mRegistry.removeObserver(this)
时,依据源码:
@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("removeObserver");
mObserverMap.remove(observer);
}
能够发现这儿直接会把this
从链表中删去,即这时mObserverMap
为空的。
然后履行mRegistry.add(newObserver)
,依据前面源码可知需求进步newObserver
的状况,j核算进步状况办法为calculateTargetState()
:
//核算一个observer的希望方针State
private State calculateTargetState(LifecycleObserver observer) {
//获取该observer链表的前一个节点 1
Map.Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
//前一个节点的状况 2
State siblingState = previous != null ? previous.getValue().mState : null;
//获取parentState状况 3
State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
: null;
//回来最小者 4
return min(min(mState, siblingState), parentState);
}
static State min(@NonNull State state1, @Nullable State state2) {
return state2 != null && state2.compareTo(state1) < 0 ? state2 : state1;
}
在这种状况下,代码1和2行获取的就会是null
,假设没有代码3这一行,经过min
函数核算就会回来mState
,从前面可知mState
为STARTED
状况。
这时就有问题了:this
的onStart()
办法还没有履行完,在它后边的调查者状况只能小于它,即newObserver
被添加进来后,状况应该被进步到CREATED
,而不是STARTED
。
那这时代码行3就有了效果,经过检查代码,咱们能够发现,在履行事情分发的forwardPass()
办法中,会记载分发前的状况,然后分发完再移除,经过这个逻辑,代码行3就能够获取现已被删去的this
状况:CREATED
,这也就契合逻辑了。
剖析完添加调查者后,首要逻辑的处理Event
和添加/删去调查者就说完了,咱们来聊一些不是十分重要的知识点。
首要便是前面故意疏忽的添加observer
时,对调查者的封装了,调用代码如下:
public void addObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("addObserver");
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
...
}
这儿的类是ObserverWithState
,它封装了调查者,首要效果是持有状况和派发事情(回调事情),类界说如下:
static class ObserverWithState {
//调查者所持有的状况
State mState;
//调查者事情回调函数
LifecycleEventObserver mLifecycleObserver;
//结构办法
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
//派发事情
void dispatchEvent(LifecycleOwner owner, Event event) {
//该Event的方针State
State newState = event.getTargetState();
//取最小值
mState = min(mState, newState);
//事务代码履行
mLifecycleObserver.onStateChanged(owner, event);
//事务代码履行后,切换到新状况
mState = newState;
}
}
这个dispatchEvent()
办法中内容的履行次序,在前面解释mParentStates
字段效果时说过了,会先进行回调,再设置新的状况。
这儿结构函数中,运用Lifecycling
中的静态办法,把空办法接口LifecycleObserver
经过转化,变成了有办法的一致的LifecycleEventObser
类型,这样咱们在dispatchEvent
办法中直接运用onStateChanged
进行回调即可。
实际上,完结了LifecycleObserver
这个空办法接口的类,有3种途径能够收到派发的Event
,分别是前面所说过的LifecycleEventObser
子类和FullLifecycleObser
子类,还有一种办法是经过注解完结的,比方下面调查者:
class CustomObserver : LifecycleObserver{
//会收到`ON_RESUME`事情时调用该办法
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connectGps(){
...
}
}
在实际写的时分,会发现这种办法现已被废弃了,官方不引荐这种写法,原因也十分简略,这种经过注解生成类的办法,功率比较低,主张运用DefaultLifecycleObserver
接口。
还有一个知识点便是用来保存调查者的集和FastSafeIterableMap
,它到底和咱们常见的集和有什么特殊之处,咱们来简略剖析剖析。
经过源码注释,咱们知道它其实是一个简易版的LinkedHashMap
,在迭代时能够修改增删元素,线程不安全,比较于SafeIterableMap
会耗费更多内存,是典型的空间换时间的战略,类图如下:
classDiagram
SafeIterableMap <|-- FastSafeIterableMap
class FastSafeIterableMap{
-HashMap<K, Entry<K, V>> mHashMap
~get(K k) Entry
~putIfAbsent(@NonNull K key, @NonNull V v)
~remove(@NonNull K key)
~contains(K key)
~ceil(K k) Entry
}
这儿供给了增删改查的常规API,其实这些功用其父类SafeIterableMap
也都完结了,可是该类多了一个mHashMap
变量,也便是会耗费更多的内存,而且其API都是基于该mHashMap
的:
protected Entry<K, V> get(K k) {
return mHashMap.get(k);
}
public V putIfAbsent(@NonNull K key, @NonNull V v) {
Entry<K, V> current = get(key);
if (current != null) {
return current.mValue;
}
mHashMap.put(key, put(key, v));
return null;
}
你或许会疑问这样做的意义是什么呢?便是单纯的为了get()
操作更快,这是由于其父类SafeIterableMap
看着是一个Map
结构,可是真正完结是用链表完结的,而链表这种数据结构,查询是十分慢的。
所以咱们就来看看这个用链表伪装成Map
的SafeIterableMap
是怎么完结的。
已然是链表,所以会有头尾节点:
//头节点
Entry<K, V> mStart;
//尾节点
private Entry<K, V> mEnd;
//前后节点
static class Entry<K, V> implements Map.Entry<K, V> {
@NonNull
final K mKey;
@NonNull
final V mValue;
Entry<K, V> mNext;
Entry<K, V> mPrevious;
...
}
这儿便是了解的双向链表节点结构,咱们再来看看增删改查几个API:
//链表尾部添加一个节点
protected Entry<K, V> put(@NonNull K key, @NonNull V v) {
Entry<K, V> newEntry = new Entry<>(key, v);
//集和元素个数加一
mSize++;
//第一个节点
if (mEnd == null) {
mStart = newEntry;
mEnd = mStart;
return newEntry;
}
//尾插
mEnd.mNext = newEntry;
newEntry.mPrevious = mEnd;
mEnd = newEntry;
return newEntry;
}
//依据K,找到节点
protected Entry<K, V> get(K k) {
Entry<K, V> currentNode = mStart;
//从头开端遍历
while (currentNode != null) {
if (currentNode.mKey.equals(k)) {
break;
}
currentNode = currentNode.mNext;
}
return currentNode;
}
//删去节点
public V remove(@NonNull K key) {
//找到待删去的节点
Entry<K, V> toRemove = get(key);
if (toRemove == null) {
return null;
}
//个数减一
mSize--;
//告诉迭代器,元素被删去了
if (!mIterators.isEmpty()) {
for (SupportRemove<K, V> iter : mIterators.keySet()) {
iter.supportRemove(toRemove);
}
}
//删去的是否是头节点
if (toRemove.mPrevious != null) {
toRemove.mPrevious.mNext = toRemove.mNext;
} else {
mStart = toRemove.mNext;
}
//删去的是否是尾节点
if (toRemove.mNext != null) {
toRemove.mNext.mPrevious = toRemove.mPrevious;
} else {
mEnd = toRemove.mPrevious;
}
toRemove.mNext = null;
toRemove.mPrevious = null;
return toRemove.mValue;
}
看到这儿,你必定会说就这?为什么Google程序员要费力气用链表完结一个Map
,还不如运用HashMap
呢?
首要它是支撑在非迭代器遍历时进行删去的,不会报ConcurrentModificationException
异常,这个特性十分重要,咱们回忆一下,LifecycleRegistry
在处理Event
和addObserver()
后都有一个十分要害的步骤,便是同步,而且说了要害的sync()
函数是不会在这2个动作穿插、重复的状况下履行,可是移除调查者的removeObserver()
办法却没有任何限制。也便是说彻底能够在任何时分进行删去调查者,甚至在遍历的时分,这儿不出错,便是该链表的效果。
还有一个特色便是供给了正序和反序的迭代器,关于HashMap
来说咱们是无法操控其遍历次序是否和添加次序相同的,再结合事务剖析,前面咱们说了observerMap
中保存的调查者,对错递加的,即值和添加次序有关,而且改动链表中的值也不能打破这个规矩,所以正序和反序遍历就十分有必要。
话不多说,来看源码:
//Iterable接口完结办法,可用于快速遍历
//在迭代期间,不会包含新添加的元素
public Iterator<Map.Entry<K, V>> iterator() {
//回来一个正序迭代器
ListIterator<K, V> iterator = new AscendingIterator<>(mStart, mEnd);
//添加到迭代器行列中
mIterators.put(iterator, false);
return iterator;
}
//回来一个反序迭代器,同样在迭代期间,是无法保护新添加的元素
public Iterator<Map.Entry<K, V>> descendingIterator() {
DescendingIterator<K, V> iterator = new DescendingIterator<>(mEnd, mStart);
mIterators.put(iterator, false);
return iterator;
}
//回来一个正序迭代器,能够在迭代期间添加新元素,且能够迭代到
public IteratorWithAdditions iteratorWithAdditions() {
IteratorWithAdditions iterator = new IteratorWithAdditions();
mIterators.put(iterator, false);
return iterator;
}
//保存迭代器的集和
private WeakHashMap<SupportRemove<K, V>, Boolean> mIterators = new WeakHashMap<>();
这儿供给了3种迭代器,这3种迭代器都支撑在迭代时删去元素,其间iterator()
和descendingIterator()
回来的迭代器是ListIterator
的子类,经过传入头尾节点来进行迭代,所以在迭代中对新添加的元素是无法感知的。
关于iteratorWithAdditions()
回来的迭代器,是正序迭代,且能够感知遍历到在遍历中添加的元素。至于这3个迭代器的完结,咱们就不看细节了,无外乎便是链表操作。
这儿看一个值得学习的点,便是这个mIterators
的数据类型:WeakHashMap
。
在文章前面介绍Lifecycle
原理是时也说到了弱引证,那是用来防止内存走漏的。而这儿的WeakHashMap
则是用来节省内存,简化操作的。WeakHashMap
对存放的键值对的Key(键)
做了弱引证处理,当某个键值对没有强引证时,能够主动被移除,然后被GC收回。
假设这儿存在屡次调用迭代器的状况,尽管每次都把迭代器放进了mIterators
,可是它的内存占用不会继续添加,会在恰当时分释放这些迭代器方针的内存。至于为什么要保存这些迭代器,能够看一下上面remove()
操作,在remove()
时需求告诉迭代器,这也是这些迭代器支撑删去的原因。
ProcessLifecycleOwner
解析
前面所说的都是以Activity
和Fragment
作为生命周期持有者的状况,其实还有一种常见的状况,便是以app运用作为生命周期持有者,也便是这儿的ProcessLifecycleOwner
即进程生命周期持有者。
运用如下:
//在App的OnCreate()办法中写如下代码
//Observer接口好几种写法,按需求挑选
ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver{
//只会派发一次
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
Logger.t("BaseApp").d("onCreate")
}
//当APP可见时派发
override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
Logger.t("BaseApp").d("onStart")
}
//当APP能够交互时派发,这时APP处于前台
override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
Logger.t("BaseApp").d("onResume")
}
//当APP不行交互时派发,即退出到后台
override fun onPause(owner: LifecycleOwner) {
super.onPause(owner)
Logger.t("BaseApp").d("onPause")
}
override fun onStop(owner: LifecycleOwner) {
super.onStop(owner)
Logger.t("BaseApp").d("onStop")
}
//永久不会被派发
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
Logger.t("BaseApp").d("onDestroy")
}
})
上面的运用中,首要适用于一个场景:有些APP需求在退到后台时,需求提示弹出Toast
,比方一些银行APP。而且需求留意上面各种事情的派发次数。
老规矩,咱们仍是来看看这个整个运用的生命周期持有者是怎么派发这些事情的。
首要一个APP正常来说就一个Application
运用,所以这儿ProcessLifecycleOwner
应该坚持单例:
public static LifecycleOwner get() {
return sInstance;
}
private static final ProcessLifecycleOwner sInstance = new ProcessLifecycleOwner();
private ProcessLifecycleOwner() { }
这儿运用静态办法由JVM完结的单例,可是咱们居然发现其结构函数居然是空的,那什么当地开端逻辑事务的呢?
这儿就用到了一个小知识点,运用ContentProvider
来发动初始化逻辑,这种用法在许多开源库都有运用,这儿咱们在XML中找到如下代码:
<application>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge" >
<meta-data
android:name="androidx.lifecycle.ProcessLifecycleInitializer"
android:value="androidx.startup" />
</provider>
</application>
这儿的InitializationProvider
承继至ContentProvider
,能够用来初始化一些app的信息,而且会在Application.onCreate()
之前进行调用。
这儿触及startup
库的运用,咱们只需求知道,这儿的初始化器是界说在meta-data
中的ProcessLifecycleInitializer
:
public final class ProcessLifecycleInitializer implements Initializer<LifecycleOwner> {
//初始化的实例
@NonNull
@Override
public LifecycleOwner create(@NonNull Context context) {
//给每一个Activity都hook一个ReportFragment
LifecycleDispatcher.init(context);
//初始化事务
ProcessLifecycleOwner.init(context);
return ProcessLifecycleOwner.get();
}
//所依靠的类
@NonNull
@Override
public List<Class<? extends Initializer<?>>> dependencies() {
return Collections.emptyList();
}
}
这样逻辑才对,运用ContentProvider
咱们能够保证在Application.onCreate()
之前就开端初始化逻辑,咱们来看看init()
办法的逻辑:
static void init(Context context) {
sInstance.attach(context);
}
void attach(Context context) {
//主线程Handler
mHandler = new Handler();
//仍旧是Registry来做事情分发
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
Application app = (Application) context.getApplicationContext();
//注册Activity的事情回调
app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
@RequiresApi(29)
@Override
public void onActivityPreCreated(@NonNull Activity activity,
@Nullable Bundle savedInstanceState) {
activity.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
@Override
public void onActivityPostStarted(@NonNull Activity activity) {
//有activity触发到onStarted()
activityStarted();
}
@Override
public void onActivityPostResumed(@NonNull Activity activity) {
//有activity触发onResumed()
activityResumed();
}
});
}
...
@Override
public void onActivityPaused(Activity activity) {
//触发onPause
activityPaused();
}
@Override
public void onActivityStopped(Activity activity) {
//触发onStop
activityStopped();
}
});
}
思路十分简略,每逢一个Activity
回调其生命周期函数时,进行记载,这种逻辑在之前咱们经常在BaseActivity
中写,来完结相似功用。
具体几个办法都比较简略,这儿咱们就不做源码的复制粘贴了,便是经过2个变量mStartedCounter
和mResumedCounter
来记载有多少Activity
发动和毁掉,当为0时就阐明APP退到后台。
可是这儿完结了一个特殊场景判别,即当运用产生配置改动,比方旋转,这时生命周期会从头回调,假设只是判别数量的话,会导致旋转时也会以为是进入到后台。
为了解决这个问题,源码中加了延迟处理以及mPauseSent
等字段来加以判别,去除这种状况。
总结
不知不觉现已写了一万多字了,不得不说,这种优异的库的源码便是一座宝藏,看源码的进程真的是一个继续学习的进程,不只仅能够加深了解,更能够学习规划思路、完结思路和办法等。
仍是做个总结吧,如下:
- 当人们面临杂乱的的问题,一个有用的办法是分层和笼统,所以Lifecycle便是为了一致生命周期,供给一些公共的特色和办法,便利开发者对接。
-
在根本运用前,咱们运用
UML
类图来给出了要害类的联系,合理运用UML类图有利于快速构建联系。 -
在根本用法中,咱们简略介绍了几种运用,包含:
- 监听Lifecycle所派发的生命周期事情;
- 获取当时Lifecycle状况;
- 依据别离关注点思维来简化代码,把逻辑从散落在生命周期函数中的逻辑给会集一同;
- 还有便是架构和事务别离,合理运用能够防备内存走漏,比方合作协程、Handler、Dialog等。
-
在Lifecycle解析部分中,咱们首要介绍了其间的State和Event,这儿需求深刻了解该图:
结合图中示意,了解每个State
的意义,以及要害的的downFrom
、upFrom
等办法规划思路和意义。
- 这儿咱们一向秉承一个思维便是事情驱动状况改动,
LifecycleOwner
完结类比方Activity
,派发Event
驱动Lifecycle
的状况改动,Lifecycle
再派发事情,改动其调查者状况,一同状况改动不能跨级,只能一步一步改动。 - 在
Lifecycle
原了解析部分,先是剖析了最常见的组件Activity
是在时分派发Event
的,这部分咱们触及了ReportFragment
的运用和介绍,这种奇妙运用Activity
和Fragment
联系的办法,能够看成是一种hook
,来获取Activity
生命周期回调。 - 完结
LifecycleOwner
的核心是能够正确、合理派发Event
给LifecycleRegistry
。 - 在剖析
Fragment
派发Event
中可知,有2个LifecycleOwner
,一个是Fragment
自己的,一个是其View
的,经过剖析调用链联系,咱们可得如下图:
-
经过该图咱们需求愈加了解
Event
和State
的联系,以及和对应生命周期函数调用的先后联系。一同剖析了在Fragment
中运用viewlifecycle
来替代lifecycle
的原因,便是在旧Fragment
入栈出栈,会导致重复添加调查者。 -
在
LifecycleRegistry
原理部分就比较随意了,是坚持学习心态来探求的,它是官方供给的Lifecycle
接口的完结类,能够处理多个调查者。- 在结构函数有个值得学习借鉴的点,便是把
Activity
或许Fragment
运用弱引证封装,这种能够有用防止这种重量级的组件产生内存走漏。 - 在派发事情中,由于要处理多个调查者状况同步和派发,所以这儿运用
mHandingEvent
和mNewEventOccurred
这2个flag能防止屡次履行,加快功率。 - 在派发事情和添加调查者这2个都是在主线程调用的函数,为了防止出错和功率,这儿经过多个flag来保证
sync()
办法只会运行在非嵌套动作的状况下。 - 其次咱们学习了
SafeIterableMap
这个数据接口,一同在LifecycleRegistry
中它一向坚持非递加的规矩,实际上它是由链表完结的Map,支撑在遍历时删去和添加。
- 在结构函数有个值得学习借鉴的点,便是把
-
最后便是
ProcessLifecycleOwner
的介绍,首要用于完结app处于前台、后台判别的需求,一同该库运用ContentProvider
是保证在Application
的onCreate()
之前进行初始化。