彻底掌握Android中的Lifecycle
Lifecycle 是一个生命周期感知型组件,属于 Jetpack 组件库中的一部分,其核心功能是将组件(如Activity 和 Fragment)的生命周期状态通知给观察者(LifecycleObserver)。观察者可以根据这些状态变化来执行相应的操作,如初始化资源、释放资源、更新数据等。通过使用 Lifecycle,开发者可以避免将业务代码和组件强关联,从而提高代码的可读性和可复用性。
Lifecycle使用方式
Lifecycle 的使用方式非常简单,通过 LifecycleOwner
获取 Lifecycle
对象,并添加生命周期观察者就可以了。ComponentActivity 和 Fragment 都默认实现了 LifecycleOwner
,以 Activity 为例,使用方式如下:
class LifecycleActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lifecycle)
//方式一:添加观察者(推荐)
lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
//doAction...
}
})
//方式二:添加观察者
lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() {
//doAction...
}
})
//方式三:添加观察者
lifecycle.addObserver(object : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
when (event) {
Lifecycle.Event.ON_CREATE -> {
//doAction...
}
}
}
})
}
}
推荐使用方式一添加观察者,也就是 DefaultLifecycleObserver
类型,使用更方便;方式二已被标为废弃;方式三同样不推荐,是在源码内部使用的。
举个例子,项目中需要埋点页面的停留时间,在页面可见的时候开始算起,页面不可见的时候(退出页面,切换到后台等)上报,通过 Lifecycle 就可以很优雅的实现:
/**
* 定义观察者,实现onResume和onStop方法,进行页面停留时间埋点逻辑
*/
class ExposureTimeObserver(val pageName: String): DefaultLifecycleObserver {
private var start = 0L
override fun onResume(owner: LifecycleOwner) {
start = System.currentTimeMillis()
}
override fun onStop(owner: LifecycleOwner) {
val time = System.currentTimeMillis() - start
if (time > 0) {
ReportUtil.report("exposureTime", mapOf("pageName" to pageName, "time" to time))
}
start = 0L
}
}
//使用时:
页面A:lifecycle.addObserver(ExposureTimeObserver("PageA"))
页面B:lifecycle.addObserver(ExposureTimeObserver("PageB"))
具体业务实现代码都封装在观察者中,Activity 只需注册观察者即可,将业务代码和组件间解耦,提高了代码复用性和可读性。
Lifecycle 的作用:
- 简化生命周期回调:避免在应用组件中手动实现繁琐的生命周期回调。
- 灵活性:可以与其他 Jetpack 组件(如ViewModel、LiveData等)结合使用,提供更灵活的生命周期管理方案。
- 生命周期安全性:确保在正确的生命周期状态下执行相应的操作,避免崩溃或内存泄漏。
Lifecycle 可以说是生命周期的抽象层,统一了各个组件如 Activity、Fragment 的生命周期,让业务代码可以和组件进行解耦,在编写代码时,只需考虑 Lifecycle 抽象出的生命周期方法,而不必关注组件具体的生命周期实现,从而写出更有条理且更精简的代码,更易于维护。通过理解和使用 Lifecycle,可以编写出更加健壮、可维护的代码,并提升应用的性能和用户体验。
Activity 和 Fragment 生命周期:
Lifecycle 提供的抽象层生命周期:
- onCreate
- onStart
- onResume
- onPause
- onStop
- onDestroy
对应 Lifecycle 状态机的七个事件,Lifecycle 更侧重状态机的事件,而非状态(下面也会有所体现)。
Lifecyle源码解析
Lifecycle 整体实现就是状态机 + 观察者模式,通过空白 Fragment 触发生命周期事件,驱动状态的转移,并通知对应的观察者,这就是 Lifecycle 的工作流程。下面是 Lifecycle 工作时,状态流转的流程图:
状态机状态流转表如下,可以结合上面的流程图来看。
状态/事件 | ON_CREATE | ON_START | ON_RESUME | ON_PAUSE | ON_STOP | ON_DESTROY |
---|---|---|---|---|---|---|
DESTROYED | ||||||
INITIALIZED | √ | |||||
CREATED | √ | √ | ||||
STARTED | √ | √ | ||||
RESUMED | √ |
蓝色是状态,定义了组件在其生命周期中的不同阶段,共五种:
INITIALIZED
:初始化状态,onCreate被调用之前。CREATED
:创建状态,onCreate 或 onStop 调用后。STARTED
:启动状态,onStart 或 onPause 调用后。RESUMED
:可见状态,onResume调用后。DESTROYED
:销毁状态,onDestroy 调用后。
红色是事件,共七种(ANY先忽略):
ON_CREATE
:对应 onCreate 方法。ON_START
:对应 onStart 方法。ON_RESUME
:对应 onResume 方法。ON_PAUSE
:对应 onPause 方法。ON_STOP
:对应 onStop 方法。ON_DESTROY
:对应 onDestroy 方法。ON_ANY
:匹配任何事件。
下面看一下 Lifecycle 的源码的具体实现,类间关系图如下:
Lifecycle 发挥作用的类主要有以下几个:
-
LifecycleOwner
:表示一个具有生命周期的组件,只有getLifecycle
方法,可以调用该方法拿到Lifecycle
来添加生命周期观察者,Activity 和 Fragment 都实现了 LifecycleOwner 接口。//接口定义 public interface LifecycleOwner { public val lifecycle: Lifecycle } //Activity中: public class ComponentActivity extends ComponentActivity implements LifecycleOwner,... { //可见真正干活的是 LifecycleRegistry private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); public Lifecycle getLifecycle() { return mLifecycleRegistry; } }
-
ReportFragment
:负责监听生命周期的变动,并产生对应的事件来驱动 Lifecycle 的状态改变。这里的实现在不同 Android SDK 版本上略有区别:API 大于等于 29,是通过Activity.registerActivityLifecycleCallbacks
方法监听生命周期;API 小于 29,则是通过ReportFragment
自身生命周期来驱动的。在 ComponentActivity 的 onCreate 方法中会进行 ReportFragment 的注入,源码:
class ComponentActivity { ... protected void onCreate(Bundle savedInstanceState) { ... ReportFragment.injectIfNeededIn(this); } ... }
open class ReportFragment() : android.app.Fragment() { companion object { private const val REPORT_FRAGMENT_TAG = "androidx.lifecycle.LifecycleDispatcher.report_fragment_tag" @JvmStatic fun injectIfNeededIn(activity: Activity) { //1.注入Fragment,区分SDK版本做具体实现 if (Build.VERSION.SDK_INT >= 29) { // On API 29+, we can register for the correct Lifecycle callbacks directly LifecycleCallbacks.registerIn(activity) } 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() } } } 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) } ... private fun dispatch(event: Lifecycle.Event) { //2.API小于29走这里 if (Build.VERSION.SDK_INT < 29) { dispatch(activity, event) } } @RequiresApi(29) internal class LifecycleCallbacks : Application.ActivityLifecycleCallbacks { override fun onActivityPostCreated( activity: Activity, savedInstanceState: Bundle? ) { //3.API大于等于29走这里 dispatch(activity, Lifecycle.Event.ON_CREATE) } override fun onActivityPostStarted(activity: Activity) { dispatch(activity, Lifecycle.Event.ON_START) } ... companion object { @JvmStatic fun registerIn(activity: Activity) { activity.registerActivityLifecycleCallbacks(LifecycleCallbacks()) } } } }
-
Lifecycle
:是一个抽象类, 定义了添加和移除观察者的抽象方法,实现了协程作用域的管理。还定义了有框架中用到的状态(State)和事件(Event),也有通过状态推导出事件等方法。public abstract class Lifecycle { //1.协程作用域的存储 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) public var internalScopeRef: AtomicReference<Any> = AtomicReference<Any>() //2.观察者的添加和移除 public abstract fun addObserver(observer: LifecycleObserver) public abstract fun removeObserver(observer: LifecycleObserver) //3.记录当前状态 public abstract val currentState: State //4.事件 public enum class Event { ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY, ON_ANY; //5.根据事件推导出下一状态 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") } //6.根据状态推导出驱动的事件(down和up代表不同的方向,可参考上面的流程图) public companion object { @JvmStatic public fun downFrom(state: State): Event? { return when (state) { State.CREATED -> ON_DESTROY State.STARTED -> ON_STOP State.RESUMED -> ON_PAUSE else -> null } } @JvmStatic public fun downTo(state: State): Event? { return when (state) { State.DESTROYED -> ON_DESTROY State.CREATED -> ON_STOP State.STARTED -> ON_PAUSE else -> null } } @JvmStatic public fun upFrom(state: State): Event? { return when (state) { State.INITIALIZED -> ON_CREATE State.CREATED -> ON_START State.STARTED -> ON_RESUME else -> null } } @JvmStatic public fun upTo(state: State): Event? { return when (state) { State.CREATED -> ON_CREATE State.STARTED -> ON_START State.RESUMED -> ON_RESUME else -> null } } } } public enum class State { DESTROYED, INITIALIZED, CREATED, STARTED, RESUMED; } } //...协程作用域相关的方法...
1.存储协程作用域对象,获取时才会创建。创建时通过 while 循环 + CAS 机制保证线程安全。
2.只定义了添加和移除观察者抽象方法,具体的观察者管理由 LifecycleRegistry 负责。
3.当前状态,与组件生命周期同步
5.根据生命周期触发的事件,得到事件触发后的目标状态
6.downFrom、downTo、upFrom、upTo 四个方法,xxFrom 系列返回当前状态转换到下一状态的响应事件;xxTo 系列返回流转到当前状态的驱动事件。down 和 up 表示不同方向,up 表示从前向后的流转,down 则相反。
-
LifecycleRegistry
,该类是 Lifecycle 抽象类的唯一实现,同时也是框架的核心,其内不仅维护着所有观察者和对应状态,同时也会收到驱动事件,同步状态变更,并调用对应观察者的回调方法。open class LifecycleRegistry private constructor( provider: LifecycleOwner, private val enforceMainThread: Boolean ) : Lifecycle() { //1.存储所有观察者和对应状态 private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>(); //2.组件当前状态,默认是INITIALIZED private var state: State = State.INITIALIZED //3.处理生命周期变动事件 open fun handleLifecycleEvent(event: Event) { ... } //...4.具体的同步代码,包括moveToState、sync、backwardPass、forwardPass等方法... //5.添加和移除观察者具体实现 override fun addObserver(observer: LifecycleObserver) { ... } override fun removeObserver(observer: LifecycleObserver) { ... } }
1.
FastSafeIterableMap
相当于把 SafeIterableMap 再封装了一层,SafeIterableMap存储的是<K,V>
,则它是存储的<K,<K,V>
。该类型是用链表实现的,模拟成 Map 接口,特性是支持在遍历的时候删除元素,非线程安全。2.
handleLifecycleEvent
是状态同步的入口,ReportFragment
发出生命周期变更的事件后,最终会调用到该方法,由此开始,进行观察者状态同步和触发方法回调。open fun handleLifecycleEvent(event: Event) { enforceMainThreadIfNeeded("handleLifecycleEvent") //1.获取事件触发后的目标状态,可以结合上图来看,源码在Lifecycle的targetState。 //2.调用moveToState开始同步观察者状态 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()}" } //1.将Lifecycle当前状态修改为目标状态 state = next if (handlingEvent || addingObserverCounter != 0) { newEventOccurred = true // we will figure out what to do on upper level. return } handlingEvent = true //2.同步观察者的状态,并触发对应回调 sync() handlingEvent = false //3.如果目标状态为Destroy,清空观察者 if (state == State.DESTROYED) { observerMap = FastSafeIterableMap() } }
moveToState
方法主要做了三件事:- 将 LifecycleRegistry 当前状态更改为目标状态,该状态是页面的真实状态,每个观察者也包含自己的状态
- 调用 sync() 方法,主要是让观察者自己的状态和 LifecycleRegistry 的状态进行对齐
- 如果目标状态是Destory,则清空所有观察者
下面继续看 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." ) //1.状态不同步则进行状态对齐操作 while (!isSynced) { newEventOccurred = false //2.具体的同步方法 if (state < observerMap.eldest()!!.value.state) { backwardPass(lifecycleOwner) } val newest = observerMap.newest() if (!newEventOccurred && newest != null && state > newest.value.state) { forwardPass(lifecycleOwner) } } newEventOccurred = false } //新添加的观察、最早添加的观察者和Lifecycle的状态相同才会返回false,保证map中所有观察者状态同步 private val isSynced: Boolean get() { if (observerMap.size() == 0) { return true } val eldestObserverState = observerMap.eldest()!!.value.state //返回链表第一个,最早添加的元素 val newestObserverState = observerMap.newest()!!.value.state //返回链表最后一个,最新添加的元素 return eldestObserverState == newestObserverState && state == newestObserverState }
该方法主要做的事就是状态对齐,让 LifecycleRegistry 状态和每个观察者自身的状态同步到一致,并在同步过程中调用观察者回调方法。
具体做法是先**从后往前(backwardPass)同步,然后再从前往后(forwardPass)**同步,可以对照开头的 Lifecycle 时序图,状态由 INITIALIZED -> RESUMED 是从前向后,反之就是从后向前。
两个方向的代码实现差不多,这里就从后向前以为例:
private fun backwardPass(lifecycleOwner: LifecycleOwner) { val descendingIterator = observerMap.descendingIterator() //1.遍历所有观察者 while (descendingIterator.hasNext() && !newEventOccurred) { val (key, observer) = descendingIterator.next() //2.判断观察者状态和当前状态,逐步进行同步 while (observer.state > state && !newEventOccurred && observerMap.contains(key) ) { //3.具体的同步操作 val event = Event.downFrom(observer.state) ?: throw IllegalStateException("no event down from ${observer.state}") pushParentState(event.targetState) observer.dispatchEvent(lifecycleOwner, event) popParentState() } } }
可以看到,该方法会遍历所有观察者,同步每个观察者的状态,并调用观察者对应的生命周期方法。
1.遍历所有观察者,同步每个观察者的状态
2.判断观察者状态是否大于最新状态,符合条件则进入 while 循环进行同步操作。(大于判断是因为这里只关注从后向前的同步)
3.找到观察者状态切换的下一个事件,根据事件调用观察者回调方法,并更新观察者状态。
举个例子,当进入第 2 步的时候,观察者 A 的状态是 RESUMED,而最新状态是 CREATED,此时进入第 3 步。首先通过 downFrom 找出流转到下一状态的事件(downFrom 是从后向前),也就是 ON_PAUSE,然后通过观察者的 dispatchEvent 方法分发:
fun dispatchEvent(owner: LifecycleOwner?, event: Event) { val newState = event.targetState state = min(state, newState) lifecycleObserver.onStateChanged(owner!!, event) state = newState }
dispatchEvent 方法中会回调 onPause 方法,并将状态更新为 STARTED。再回到第 2 步,STATED 仍然大于 CREATED,再进入第三步:找出 ON_STOP 事件,回调 onStop 方法,观察者状态同步为 CREATED,此时观察者 A 状态和最新状态保持一致了,这就是状态同步的流程。
注意:枚举如果没定义值,则默认是根据定义的位置来决定的
通过上面流程可以发现,状态的同步是按次序的,不能跨状态同步,可以参考上面的时序图,并不能将状态直接一步对齐成最新的状态,因为 Lifecycle 侧重事件的回调,从一个状态到另一个状态,需要找出所有导致状态变更的事件,并执行对应观察者方法。
添加新的观察者时也有相同的对齐逻辑:
override fun addObserver(observer: LifecycleObserver) { enforceMainThreadIfNeeded("addObserver") val initialState = if (state == State.DESTROYED) State.DESTROYED else State.INITIALIZED val statefulObserver = ObserverWithState(observer, initialState) val previous = observerMap.putIfAbsent(observer, statefulObserver) if (previous != null) { return } val lifecycleOwner = lifecycleOwner.get() ?: // it is null we should be destroyed. Fallback quickly return val isReentrance = addingObserverCounter != 0 || handlingEvent var targetState = calculateTargetState(observer) addingObserverCounter++ while (statefulObserver.state < targetState && observerMap.contains(observer) ) { pushParentState(statefulObserver.state) val event = Event.upFrom(statefulObserver.state) ?: throw IllegalStateException("no event up from ${statefulObserver.state}") statefulObserver.dispatchEvent(lifecycleOwner, event) popParentState() // mState / subling may have been changed recalculate targetState = calculateTargetState(observer) } if (!isReentrance) { // we do sync only on the top level. sync() } addingObserverCounter-- }
添加新的观察者一般情况默认是 INITIALIZED 状态,所以同样需要同步到最新状态。举个例子,在页面 onResume 时添加观察者,此时将观察者的回调方法都打印一下:
新添加的观察者依次调用了 onCreate、onStart 和 onResume 回调。说明 Lifecycle 侧重状态机的事件,从一个状态到另一个状态,需要找出所有导致状态变更的事件,并执行对应观察者方法,不能将某个事件漏掉,以免调用时代码出错。状态观察者:外部添加的观察者内部会包装一层,目的是保存观察者状态,方便和最新状态做对比。
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 } }
-
LifecycleObserver
:表示一个可以观察 LifecycleOwner 生命周期状态的组件。开发人员可以通过重写 DefaultLifecycleObserver 接口来监听 LifecycleOwner 的生命周期状态变化,并实现对应逻辑。public interface DefaultLifecycleObserver : LifecycleObserver { public fun onCreate(owner: LifecycleOwner) {} public fun onStart(owner: LifecycleOwner) {} public fun onResume(owner: LifecycleOwner) {} public fun onPause(owner: LifecycleOwner) {} public fun onStop(owner: LifecycleOwner) {} public fun onDestroy(owner: LifecycleOwner) {} }
之所以可以直接使用 DefaultLifecycleObserver,是因为源码内部还通过适配器模式进行了版本兼容,这也是适配器模式的经典用法。源码如下:
internal class DefaultLifecycleObserverAdapter( private val defaultLifecycleObserver: DefaultLifecycleObserver, private val lifecycleEventObserver: LifecycleEventObserver? ) : LifecycleEventObserver { override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) { when (event) { Lifecycle.Event.ON_CREATE -> defaultLifecycleObserver.onCreate(source) Lifecycle.Event.ON_START -> defaultLifecycleObserver.onStart(source) Lifecycle.Event.ON_RESUME -> defaultLifecycleObserver.onResume(source) Lifecycle.Event.ON_PAUSE -> defaultLifecycleObserver.onPause(source) Lifecycle.Event.ON_STOP -> defaultLifecycleObserver.onStop(source) Lifecycle.Event.ON_DESTROY -> defaultLifecycleObserver.onDestroy(source) Lifecycle.Event.ON_ANY -> throw IllegalArgumentException("ON_ANY must not been send by anybody") } lifecycleEventObserver?.onStateChanged(source, event) } }
为什么State不是设置为7种呢?
Lifecycle 中有两个很奇怪的状态,分别是 CREATED 和 STARTED,先说 CREATED 状态,通过 ON_CREATE 事件转换为 CREATED 状态可以理解,但通过 CREATED 事件也转换为 CREATED 似乎有些不合常理;STARTED 状态也是一样,为什么 Google 工程师没有再新建两个 STOPED 和 PAUSED 状态呢?个人认为 Lifecycle 侧重的是事件而非状态,CREATED 或 STOPED 状态对于上层来说区别不大,Lifecycle 比较关注的状态可能只有已经定义的五个了。其次复用这两种状态,少了两个枚举,更节省内存。缺点就是代码复杂些,就上述流程图来说,状态的流转并不是单向的了,而是双向的,这就需要根据旧状态和新状态判断方向,从而推断出驱动状态转换的事件,继而调用对应的生命周期方法回调。如此非常巧妙的设计,让人叹为观止。
总结
Lifecycle 是状态机 + 观察者模式的结合,通过 ReportFragment 触发事件,驱动 LifecycleRegistry 中所有观察者状态同步,并根据同步结果触发观察者对应的回调方法,这就是它的整体原理。
Lifecycle 虽然只是提供了抽象层的组件生命周期监听,但这一改变可以让软件编码灵活性大大加强,LiveData 就是基于 Lifecycle 来实现的。通过使用 Lifecycle,可以编写出更加健壮、可维护的代码,提升应用的性能和用户体验。
空白 Fragment 监听生命周期的方式也有很多优秀的三方库在用,比如 Glide,通过这种方式来监听生命周期,处理图片的加载和回收。一些动态权限处理三方库,通过添加空白 Fragment 来监听权限请求结果,从而简化调用处代码,优秀的思路都是相通的。
参考:
官方文档:Lifecycle
状态机:重修设计模式-行为型-状态模式
观察者模式:重修设计模式-行为型-观察者模式