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
,以及在哪些场景下需要使用。欢迎指正与收藏。谢谢