Android Jetpack组件架构:Lifecycle的使用和原理
导言
作为Jetpack中关于生命周期管理的核心组件,Lifecycle组件是其他比如LiveDate和ViewModel等组件的基础,本篇文章主要就将介绍关于Lifecycle的使用和它的运作原理。
Lifecycle的使用
我们先从Google官网上拉一段示例代码:
class MyObserver : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
connect()
}
override fun onPause(owner: LifecycleOwner) {
disconnect()
}
}
myLifecycleOwner.getLifecycle().addObserver(MyObserver())
可以看到这段代码首先是实现了DefaultLifecycleObserver
接口,并且实现了其中的两个方法,这两个方法就是在Lifecycle组件的生命状态发生改变的时候触发的,具体来说它的作用和Activity中的各种生命周期的回调差不多。那为什么还要引入Lifecycle
组件呢?原因就是为了解耦,这些年来Google越来越推崇MVVM架构,这个架构的核心思想之一就是将Activity进行解耦,尝试不要再Activity中加入过多的业务代码,要是我们直接将方法写在Activity中的话会显得整个Activity都很臃肿,切不利于我们管理,所以引入了Lifecycle
组件来帮助我们管理与生命周期相关的回调。 除此之外,Lifecycle
组件也是许多jetpack之中其他组件的基础。
Lifecycle的原理
Lifecycle的状态和事件
这整个Lifecycle中有两个重要的信息,一个是Lifecycle当前的状态,另一个Lifecycle状态变化而引起的事件,具体如下所示:
我们也可以在源码中找到:
public enum class State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public fun isAtLeast(state: State): Boolean {
return compareTo(state) >= 0
}
}
public enum class Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY;
.......
}
可以看到是由两个枚举类来实现的,按照Google官方文档的说法,我们可以可以将状态看作图中的节点,将事件看作这些节点之间的边(上图中)。一旦Lifecycle
的状态由一个转变到另一个,就会触发它的Event事件,这个事件会被分发到观察者之中去执行响应的回调方法。
LifecycleOwner接口
LifecycleOwner的作用就是标记一个类具有生命周期,或者更具体地说,表明这个类可以由Lifecycle
框架所管理,这个接口只有一个方法(成员变量),是用于获取具体的Lifecycle
对象的:
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
public val lifecycle: Lifecycle
}
在Kotlin版本中这个类还有一个指向协程作用域的变量,可以在创建协程时使用:
public val LifecycleOwner.lifecycleScope: LifecycleCoroutineScope
get() = lifecycle.coroutineScope
这个接口从各个类中(具体来说是Fragment或者Activity等组件)抽象出了生命周期,并将其提供给其他组件来使用。
Activity中的Lifecycle来源
Activity肯定是一个有生命周期的组件,并且我们也可以通过getLifecycle
方法获取到具体的生命周期对象,我们可以点进去,发现这个方法返回的是一个ComponentActivity
类的成员变量,这个ComponentActivity
类是Activity的父类:
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
可以看到这个Activity中Lifecycle是由LifecycleRegistry
实现的,一般情况下我们也是用这个类来实现Lifecycle的实体的。这个类为了防止内存泄漏是用弱引用来存储LifecycleOwner的(此处具体来说就是ComponentActivity):
private val lifecycleOwner: WeakReference<LifecycleOwner>
初次之外,其中还有几个成员变量我们先来提前介绍一下:
private var state: State = State.INITIALIZED //Lifecycle当前的State,初始化时默认是INITIALIZED
private var observerMap = FastSafeIterableMap<LifecycleObserver, ObserverWithState>() //存储观察者的表,该表支持在迭代中修改
private var handlingEvent = false //标志位,判断当前Lifecycle是否正在处理事件
ReportFragment–用来追踪Activity生命周期变化
这里我们还是需要返回到ComponentActivity
中去,Activity的Lifecycle状态是在哪里修改的呢?
@CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
Lifecycle lifecycle = getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED);
}
super.onSaveInstanceState(outState);
mSavedStateRegistryController.performSave(outState);
}
可以看到此处方法中的第三行将当前Lifecycle的状态设置为了CREATED
,具体是从INITIALIZED
转变过去的。不过以一般的角度思考,正常应该是在ComponentActivity
中的各个生命周期回调中改变,对于Actvity来说,它将这个任务交给了一个特殊的Fragment–ReportFragment
,这个Fragment是在onCreate
中创建出来的:
protected void onCreate(@Nullable Bundle savedInstanceState) {
mSavedStateRegistryController.performRestore(savedInstanceState);
mContextAwareHelper.dispatchOnContextAvailable(this);
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this); //注入ReportFragment
if (BuildCompat.isAtLeastT()) {
mOnBackPressedDispatcher.setOnBackInvokedDispatcher(
Api33Impl.getOnBackInvokedDispatcher(this)
);
}
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
具体就是标注出来的ReportFragment.injectIfNeededIn(this)
,从命名可以看出来是一个注入方法,它将一个ReportFragment注入到了ComponentActivity之中里去了:
@JvmStatic
fun injectIfNeededIn(activity: Activity) {
if (Build.VERSION.SDK_INT >= 29) {
// On API 29+, we can register for the correct Lifecycle callbacks directly
LifecycleCallbacks.registerIn(activity)
}
// Prior to API 29 and to maintain compatibility with older versions of
// ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
// need to support activities that don't extend from FragmentActivity from support lib),
// use a framework fragment to get the correct timing of Lifecycle events
val manager = activity.fragmentManager
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(ReportFragment(), REPORT_FRAGMENT_TAG).commit()
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions()
}
}
这个方法首先会判断当前API版本是否大于29,如果大于就直接调用LifecycleCallbacks.registerIn(activity)
方法进行注册,否则会通过Activity的FragmentManager来将ReportFragment添加进去。这个API判断不重要,反正最后做到的效果就是ComponentActivity之中有了一个用来追踪生命周期的ReportFragment
了。
ReportFragment感知生命周期变化
由于是Fragment,其生命周期是由FragmentManager管理的,而这个FragmentManager又是Actvity的一部分,所以当Actvity的状态发生改变的时候会触发FragmentManager进行事件的分发,进而触发其管理下的Fragment的生命周期的变化。**总之我们记住一点,这个ReportFragment可以感知到Activity的生命周期变化。**所以,Lifecycle状态的变更应该是会在这个特殊的Fragment之中进行的,我们来看它的onActivityCreated
方法:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
dispatchCreate(processListener)
dispatch(Lifecycle.Event.ON_CREATE)
}
override fun onStart() {
super.onStart()
dispatchStart(processListener)
dispatch(Lifecycle.Event.ON_START)
}
override fun onResume() {
super.onResume()
dispatchResume(processListener)
dispatch(Lifecycle.Event.ON_RESUME)
}
override fun onPause() {
super.onPause()
dispatch(Lifecycle.Event.ON_PAUSE)
}
可以看到不仅仅是onActivityCreated
方法,它的其他生命周期的回调中也调用了dispatch
方法,从名字就可以看出来这是一个用来分发生命周期事件的方法,马上进入到这个方法之中:
@JvmStatic
internal fun dispatch(activity: Activity, event: Lifecycle.Event) {
if (activity is LifecycleRegistryOwner) {
activity.lifecycle.handleLifecycleEvent(event)
return
}
if (activity is LifecycleOwner) {
val lifecycle = (activity as LifecycleOwner).lifecycle
if (lifecycle is LifecycleRegistry) {
lifecycle.handleLifecycleEvent(event)
}
}
}
可以看到主要是调用到了Activity内部的Lifecycle对象进行事件的处理。
Lifecycle处理生命周期事件
上面说到通过handleLifecycleEvent
方法进行生命周期事件的处理,我们再来看这个方法:
open fun handleLifecycleEvent(event: Event) {
enforceMainThreadIfNeeded("handleLifecycleEvent")
moveToState(event.targetState)
}
private fun moveToState(next: State) {
if (state == next) {
return
}
check(!(state == State.INITIALIZED && next == State.DESTROYED)) {
"no event down from $state in component ${lifecycleOwner.get()}"
}
state = next
if (handlingEvent || addingObserverCounter != 0) {
newEventOccurred = true
// we will figure out what to do on upper level.
return
}
handlingEvent = true
sync()
handlingEvent = false
if (state == State.DESTROYED) {
observerMap = FastSafeIterableMap()
}
}
这里可以看到,主要是触发了moveToState
方法,其中还涉及到event.target
的取值,我们先来看这个event.target
:
public val targetState: State
get() {
when (this) {
ON_CREATE, ON_STOP -> return State.CREATED
ON_START, ON_PAUSE -> return State.STARTED
ON_RESUME -> return State.RESUMED
ON_DESTROY -> return State.DESTROYED
ON_ANY -> {}
}
throw IllegalArgumentException("$this has no target state")
}
这个方法也很好懂,根据传入的事件判断接下来Lifecycle的状态(State),如果忘了我们再来看一下那张图,可以发现完全对的上:
那么接下来的moveToState
方法也很好懂了,就是将当前Lifecycle的状态转变到另一个状态,首先当目标状态和当前状态一致的话不会执行任何动作,接下来就直接返回。之后比较重要的部分就是sync
方法了,在执行sync
方法之前会将handingEvent
标志位置为true,标志Lifecycle目前正在处理事件。至于这个sync
方法,看名字也知道是一个用来同步内部状态的方法,具体同步的是什么呢?我们接下来继续看sync
方法。
sync方法:
private fun sync() {
val lifecycleOwner = lifecycleOwner.get()
?: throw IllegalStateException(
"LifecycleOwner of this LifecycleRegistry is already " +
"garbage collected. It is too late to change lifecycle state."
)
while (!isSynced) { .//当当前Lifecycle还没有完成同步的话
newEventOccurred = false //新事件发生标志位为false
if (state < observerMap.eldest()!!.value.state) { //判断状态转变方向
backwardPass(lifecycleOwner) //向前转变
}
val newest = observerMap.newest()
if (!newEventOccurred && newest != null && state > newest.value.state) {
forwardPass(lifecycleOwner) //向后转变
}
}
newEventOccurred = false
}
首先while的判断条件是当前Lifecycle是否已经完成了必要的同步,如果还没有完成的话接下来就要进行同步。之前的方法中我们已经获得了当前Lifecycle之后要转变的状态,但是如果我们继续回看上面那张图就会发现光有一个目标状态还不行,还要判断转变的方法,比如说CREATED
状态和STARTED
状态,如果是向后转变要触发的应该是ON_START
事件,反之则应该是ON_STOP
事件。这里的if (state < observerMap.eldest()!!.value.state)
以及后边的那个if分支就是用来判断状态转变的方向的。这里会涉及到观察者的生命周期,这里我们先不管,**先知道这里判断出了状态转变的方向。**我们以forwardPass
方法为例看其实现。
forwardPass方法:
private fun forwardPass(lifecycleOwner: LifecycleOwner) {
@Suppress()
val ascendingIterator: Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> =
observerMap.iteratorWithAdditions()
while (ascendingIterator.hasNext() && !newEventOccurred) {
val (key, observer) = ascendingIterator.next()
while (observer.state < state && !newEventOccurred && observerMap.contains(key)
) {
pushParentState(observer.state)
val event = Event.upFrom(observer.state)
?: throw IllegalStateException("no event up from ${observer.state}")
observer.dispatchEvent(lifecycleOwner, event)
popParentState()
}
}
}
首先会获得整个Lifecycle的Observer集合的迭代器,并且在第二个while循环中会将状态低于当前State的观察者Observer,所谓状态低我们也可以看上面那幅图,越靠近左边是State的值越小。这里我们又要考虑到这个方法是将状态向后移的情况,所以之前观察者集合中的State显然是不可能比当前State大的,所以说只要考虑observer.state < state
的情况就好了。
然后会通过Event.upFrom
方法获得观察者所需要的事件然后发送给对应的观察者,这样观察者就会触发其回调了,具体是observer.dispatchEvent(lifecycleOwner, event)
这一行,我们来看dispatchEvent方法,这是ObserverWithState类的方法:
internal class ObserverWithState(observer: LifecycleObserver?, initialState: State) {
var state: State
var lifecycleObserver: LifecycleEventObserver
init {
lifecycleObserver = Lifecycling.lifecycleEventObserver(observer!!)
state = initialState
}
fun dispatchEvent(owner: LifecycleOwner?, event: Event) {
val newState = event.targetState
state = min(state, newState)
lifecycleObserver.onStateChanged(owner!!, event)
state = newState
}
}
可以看到这个类主要是有两个成员变量,一个是观察者当前的状态,这个当前的状态的意思就是执行完当前Lifecycle的事件之后记录下的对应Lifecycle的State,可以说它记录的就是Lifecycle发生本次事件传递之前的状态。在其dispatchEvent
方法之中最终会调用到lifecycleObserver
方法,这个方法不用多说就是我们注册时传入的实现了观察者接口的方法。到这里就完成了整个Lifecycle生命感知和事件传递的过程,我们再用一幅图来总结一下:
LifecycleObserver接口
最后我们再来说明一下LifecycleObserver接口,具体来说这是一个标签接口,该标签的意义就是标记一个类可以用来观察Lifecycle。如果看过一些老旧的书的话,我们会发现之前这个Lifecycle的回调是用OnLifecycleEvent
注解实现的,不过他现在已经被废弃了。
LifecycleObserver有两个具体子接口:DefaultLifecycleObserver
和LifecycleEventObserver
,这两个都是可以使用的,不过一般情况下我们使用DefaultLifecycleObserver就可以了。这两个类之间也存在优先级的关系,DefaultLifecycleObserver的优先级是高于LifecycleEventObserver的,这是什么意思呢?就是一个类可以即实现DefaultLifecycleObserver
类,又实现LifecycleEventObserver
,这种情况下DefaultLifecycleObserver的回调将先于LifecycleEventObserver发生。
最后我们也来附一张图: