lifecycle是什么?我将通过这篇文章,梳理并讲解清楚。在 Android 中,通常所说的生命周期 (lifecycle) 指的是一个 Activity、Fragment 或其他应用组件从创建到销毁的整个过程。这不是我们这篇讲解的点。
这里主要讲解:androidx.lifecycle ,是一个 Android Jetpack 组件,它是现代 Android 架构中处理生命周期的官方解决方案 。它不仅仅指 Activity 或 Fragment 的生命周期回调,而是提供了一套完整的工具和接口,让开发者能够构建生命周期感知型组件
为什么要使用 androidx.lifecycle?
- 解耦 : 它将业务逻辑和视图逻辑彻底解耦。你不再需要在 Activity/Fragment 中手动处理大量的生命周期回调。
LifecycleObserver可以在外部处理,让你的 Activity 变得更简洁。 - 避免内存泄漏 :
LiveData只有在观察者活跃时才发送更新,当观察者被销毁时,它会自动移除绑定。这从根本上避免了因观察者未解绑而导致的内存泄漏。 - 跨越配置更改 : 配合
ViewModel,可以轻松地在屏幕旋转等配置更改后恢复数据,极大地提升了用户体验。
总结来说,androidx.lifecycle 不仅仅是"一个生命周期",而是一个强大的工具集。它将生命周期管理提升到了一个新的层次,让开发者能够编写出更健壮、更易维护、更解耦的 Android 应用。
大体上分为下面这些:
1、Lifecycle
Lifecycle 是一个抽象类,这是重点 ,它负责存储生命周期的状态和事件 。每个 LifecycleOwner 都会有一个 Lifecycle 对象。
Lifecycle.State: 枚举了组件的当前状态,例如INITIALIZED,CREATED,STARTED,RESUMED,DESTROYED。Lifecycle.Event: 枚举了从一个状态转换到另一个状态的事件,例如ON_CREATE,ON_RESUME,ON_PAUSE,ON_DESTROY
2、LifecycleOwner
LifecycleOwner 是一个接口,这是重点 。任何实现它的类都可以拥有一个生命周期对象 (Lifecycle) ,就是接口里已经包含了Lifecycle这个抽象类。它是整个生命周期感知的核心,所有感知都是基于这个接口。

ComponentActivity 和 Fragment 都已经默认实现了这个接口,所以它们可以作为生命周期的宿主,现在mvi/mvvm模式下,都是使用这个:
- 在activity里一般直接使用this就可以了。
- fragment一般使用this.viewLifecycleOwner,后面会说明为什么
ViewModel
ViewModel 也是一个核心组件。它与 LifecycleOwner 关联,但其生命周期跨越了配置更改 。ViewModel 本身不实现 LifecycleOwner,但它经常与 LiveData或StateFlow 配合使用,来响应宿主的生命周期变化。
3、LifecycleObserver
LifecycleObserver 是一个标记接口,它代表一个生命周期感知型组件 。实现了这个接口的类可以在宿主(如 Activity)的生命周期状态发生变化时,自动接收到通知。
- 实现方式 : 你可以在
LifecycleObserver的方法上使用@OnLifecycleEvent注解,来指定在哪个生命周期事件发生时执行特定的代码
Kotlin
class MyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connectListener() {
// 在宿主 Activity 的 onResume() 时执行
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun disconnectListener() {
// 在宿主 Activity 的 onPause() 时执行
}
}
4、ViewTreeLifecycleOwner
在 androidx.lifecycle 出现之前,我们通常只能通过 Activity 或 Fragment 来获取生命周期对象。但在一些复杂场景下,比如自定义 View 或 RecyclerView 中的列表项,我们希望这些视图也能感知生命周期,以便在适当的时机执行或停止某些操作。
ViewTreeLifecycleOwner 的出现正是为了解决这个问题。它是一个 Jetpack 库 中的工具类,通过它,你可以将一个 LifecycleOwner(比如 Activity 或 Fragment)绑定到整个视图层次结构中。这样我们自己在实现LifecycleObserver,就可以感知生命周期。
核心原理
ViewTreeLifecycleOwner 的核心原理是利用 View 的 setTag() 和 getTag() 方法。当一个 Activity 或 Fragment 的内容视图 (content view) 被设置时,ViewTreeLifecycleOwner 会将自身(一个 LifecycleOwner 实例)作为一个 tag 存入到视图层次结构的根视图中。
这样一来,视图层次结构中的任何一个子 View 都可以通过一个简单的静态方法来获取到它所属的 LifecycleOwner,而无需知道它的父 Activity 或 Fragment。
如何使用,后续将不再讲解
假设你有一个自定义 View,你想让它在屏幕上可见时开始执行动画,在不可见时暂停。在以前,你可能需要通过接口或回调,手动将 Activity 的 onResume() 和 onPause() 事件传递给这个 View,这会造成代码的耦合和复杂性。
有了 ViewTreeLifecycleOwner,事情就变得简单多了。
Kotlin
// 1、获取LifecycleOwner: 在你的自定义 View中,
// 你可以通过静态方法 ViewTreeLifecycleOwner.get(view) 来获取它所属的 LifecycleOwner
val lifecycleOwner = ViewTreeLifecycleOwner.get(this)
// 2、拿到 lifecycleOwner 后,你就可以像在Activity或Fragment中一样,
// 添加一个 LifecycleObserver来监听生命周期事件
lifecycleOwner?.lifecycle?.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun startAnimation() {
// 在宿主组件(如 Activity)恢复时开始动画 // 此时 View 必定是可见的
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun stopAnimation() {
// 在宿主组件暂停时停止动画 // 此时 View 已经不可见
}
}
下面来具体说说LifecycleOwner
LifecycleOwner 的主要实现者
LifecycleOwner 是 Android 现代架构中非常核心的接口,它将生命周期抽象出来,并与组件解耦。
Activity和Fragment是最常见的LifecycleOwner,因为它们是 UI 界的直接代表。Service也可以成为LifecycleOwner,用于后台任务。ProcessLifecycleOwner代表了整个应用进程的生命周期。View则通过ViewTreeLifecycleOwner机制,间接地获取LifecycleOwner的能力,实现更灵活的生命周期管理。
通过这些实现了 LifecycleOwner 的组件,开发者可以编写出更加健壮、易于维护、并且没有内存泄漏问题的代码。
Activity与Fragment是如何关联的
Activity 和 Fragment 与 LifecycleOwner 的关联,并不是简单的实现接口那么简单,而是一个精心设计的流程,以确保生命周期的正确传递和管理
Activity 与 LifecycleOwner 的关联
在现代 Android 中,Activity 与 LifecycleOwner 的关联主要依赖于 ComponentActivity。
ComponentActivity 的作用
ComponentActivity 是 androidx.activity 库中的一个基类,它是所有现代 Activity(包括 AppCompatActivity)的父类。它在内部实现了一些关键逻辑,其中就包括对 LifecycleOwner 的支持。
关联过程
-
实现
LifecycleOwner接口 :ComponentActivity本身就实现了LifecycleOwner接口,并持有一个LifecycleRegistry实例。LifecycleRegistry是Lifecycle的具体实现,它负责存储当前生命周期状态,并向观察者分发事件。 -
通过
ReportFragment传递事件 :ComponentActivity在onCreate()方法中,会注册一个特殊的、不可见的Fragment------ReportFragment。这个Fragment的唯一任务就是监听Activity的生命周期回调(如onResume,onPause等),然后将这些回调事件转发给LifecycleRegistry。- 当
Activity的onResume()被调用时,ReportFragment会捕获这个事件,并告诉LifecycleRegistry,Lifecycle的状态现在应该变为RESUMED。 - 当
Activity的onPause()被调用时,ReportFragment也会捕获它,并通知LifecycleRegistry,状态应该变为PAUSED。
- 当
这个机制巧妙地将 Activity 的生命周期回调与 LifecycleRegistry 解耦,ComponentActivity 只需要在 onCreate 中注册一次,之后所有的生命周期管理都由 ReportFragment 和 LifecycleRegistry 自动处理。
Fragment 与 LifecycleOwner 的关联
Fragment 与 LifecycleOwner 的关联比 Activity 稍微复杂一些,因为 Fragment 既有自己的生命周期,又有视图的生命周期。
Fragment 自身的 LifecycleOwner
Fragment 本身也实现了 LifecycleOwner 接口。它的生命周期从 onAttach() 开始,到 onDetach() 结束。Fragment 内部同样持有一个 LifecycleRegistry 实例,并在自己的生命周期回调方法中,手动更新 LifecycleRegistry 的状态。
例如,在 onStart() 中,Fragment 会调用 lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)。
viewLifecycleOwner 的关联
viewLifecycleOwner 是 Fragment 最关键的生命周期概念之一。它用于将 Fragment 的视图生命周期与一个独立的 LifecycleOwner 关联起来。
关联过程如下:
- 创建
viewLifecycleOwner: 在Fragment的onCreateView()方法执行完毕后,Fragment会创建一个LifecycleOwner实例 ,并将其生命周期与视图的生命周期同步。这个LifecycleOwner就是viewLifecycleOwner。 - 绑定到视图树 :
Fragment会利用ViewTreeLifecycleOwner这个工具,将新创建的viewLifecycleOwner绑定到视图层次结构的根视图上。它会调用ViewTreeLifecycleOwner.set(view, viewLifecycleOwner)。 - 自动传递事件 : 当
Fragment的视图被添加到窗口(onStart)或从窗口移除(onStop)时,Fragment会自动更新viewLifecycleOwner的生命周期状态。当视图被销毁(onDestroyView)时,viewLifecycleOwner的生命周期也会进入DESTROYED状态。
总结
- Activity :通过
ComponentActivity在onCreate()中注册一个ReportFragment,由该Fragment监听Activity的生命周期并更新LifecycleRegistry。 - Fragment :既有自己的
LifecycleOwner,又通过viewLifecycleOwner专门管理视图的生命周期。viewLifecycleOwner通过ViewTreeLifecycleOwner绑定到视图树,确保视图与生命周期的严格同步。
这种分层和代理的设计,使得开发者能够以统一的方式管理不同组件的生命周期,同时解决了 Fragment 视图生命周期与实例生命周期不一致的难题,这是现代 Android 架构健壮性的基石。
为什么要有fragment里要使用viewLifecycleOwner
通过上面的描述你应该能够大体知道原因了:viewLifecycleOwner 专门管理视图的生命周期。
在 Fragment 中观察 LiveData 时,传入 this 作为 LifecycleOwner 在某些情况下会导致问题。正确的做法是传入 viewLifecycleOwner。
-
Fragment的生命周期比它的视图(View)的生命周期要长。一个Fragment可以被创建,但它的视图可能被销毁并重新创建多次(例如,在BackStack中进出)。如果你传入
this,观察者会绑定到Fragment整个生命周期。当Fragment的视图被销毁(onDestroyView被调用)而Fragment本身仍然存在时,观察者仍然活跃。此时,LiveData的更新会试图去更新一个已经不存在的视图,这可能导致 内存泄漏 或 空指针异常。 -
viewLifecycleOwner(Fragment 的视图生命周期) :Fragment提供了一个特殊的属性viewLifecycleOwner。它的生命周期范围精确地 与Fragment的视图生命周期相匹配。- 当
Fragment的视图被创建时 (onCreateView),viewLifecycleOwner的生命周期开始。 - 当
Fragment的视图被销毁时 (onDestroyView),viewLifecycleOwner的生命周期结束。
因此,在
Fragment中,正确的观察方式是:KotlinviewModel.someLiveData.observe(viewLifecycleOwner, Observer { data -> // 更新 UI })这样做可以确保观察者只在视图存在且可见时才接收更新,并且在视图被销毁时自动移除观察者,从而避免了内存泄漏。
- 当
最后
系统通过上面的讲解能让你明白如何使用 Lifecycle,以及在哪些场景下需要使用。欢迎指正与收藏。谢谢