跳到主要内容Jetpack Lifecycle 核心机制与源码深度解析 | 极客日志Kotlinjava
Jetpack Lifecycle 核心机制与源码深度解析
详细梳理了 Android Jetpack Lifecycle 组件的核心机制与源码实现。内容涵盖 Lifecycle 的定义、状态与事件枚举、依赖配置、生命周期管理的重要性及常见问题。重点分析了 Lifecycle 抽象类、LifecycleRegistry 实现类、LifecycleOwner 接口以及 ReportFragment 注入机制的工作原理。通过源码解析 sync 方法、forwardPass 和 backwardPass 逻辑,阐述了观察者模式在生命周期管理中的应用。最后提供了 DefaultLifecycleObserver 的使用示例、自定义生命周期组件的实践以及常见陷阱与最佳实践,帮助开发者深入理解并正确使用 Lifecycle 构建健壮的应用架构。
片刻1 浏览 Jetpack Lifecycle 核心机制与源码深度解析
一、引言
Android Jetpack 系列组件推出已有一段时间,作为架构组件的基础设施,它使得开发过程更加规范化。遵循谷歌推荐的最佳实践不仅能让 App 更加健壮、体验更优,还能在代码层面实现简洁优雅,消除冗余的样板代码。
Lifecycle 是 Jetpack 的基石之一,用于生命周期感应型组件的构建。它允许其他对象根据 Activity 或 Fragment 的生命周期状态自动调整自身行为。本文将系统梳理 Lifecycle 的核心概念、依赖配置、管理重要性以及源码实现细节,帮助开发者深入理解其工作原理。
二、Lifecycle 是什么?
Lifecycle 是一个抽象类,用于存储有关组件(Activity、Fragment)的生命周期状态信息,并允许其他对象观察此状态。通过 Lifecycle,我们可以解耦业务逻辑与生命周期回调,避免内存泄漏和状态不一致问题。
1. 核心枚举:事件与状态
Lifecycle 使用两种主要的枚举来跟踪相关组件的生命周期状态:
- Events(事件):从框架和类分派的生命周期事件。这些事件映射到 Activity 和 Fragment 中的回调事件,如
ON_CREATE, ON_START, ON_RESUME 等。
- States(状态):由 Lifecycle 对象跟踪的组件的当前状态。包括
INITIALIZED, CREATED, STARTED, RESUMED, DESTROYED。
官方结构图展示了状态流转关系,通常是从 INITIALIZED 开始,经过 CREATED, STARTED, RESUMED,最终到达 DESTROYED。
三、依赖配置
早期的依赖 lifecycle-extensions 已弃用。现在建议为特定 Lifecycle 工件添加所需的依赖项。以下是推荐的 Gradle 配置:
dependencies {
val lifecycle_version = "2.6.0"
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")
}
一般在使用 Lifecycle 时,都会搭配 ViewModel、LiveData 一起使用,构建数据驱动 UI 型应用。循序渐进地掌握 Lifecycle 有助于深刻理解 Android 架构组件。
四、生命周期的管理重要性
Android 中的内存泄漏问题很大一部分来源于对生命周期的管理不当。资源在本应该释放的时候并没有得到释放,导致生命周期短的组件持有了生命周期长的组件,最终导致内存泄漏甚至应用 Crash。
例如,自定义 View 包含动画时,需要在 onPause 时暂停动画;Handler 需要回收消息的移除等,这些都与生命周期紧密关联。
1. 传统方式的局限性
官方的使用 Demo 展示了获取定位信息的场景:在 App 启动时开启获得定位的信息对应 onStart(),而在 onStop() 对资源进行释放。
internal class MyLocationListener(
private val context: Context,
private val callback: (Location) -> Unit
) {
fun start() {
}
fun stop() {
}
}
class MyActivity : AppCompatActivity() {
private lateinit var myLocationListener: MyLocationListener
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myLocationListener = MyLocationListener(this) { location ->
}
}
override fun onStart() {
super.onStart()
myLocationListener.start()
}
override fun onStop() {
super.onStop()
myLocationListener.stop()
}
}
虽然做到了对生命周期的管理,但这种实现存在以下问题:
- 过于理想化:假设
onStart() 和 onStop() 能顺利执行,未考虑异常情况下如何管理资源。
- 组件耦合:一个完整的 App 包含很多组件,忽略了条件竞争关系,随着系统迭代,项目不易管理。
- 重复造轮子:Glide 等库内部维护了一套生命周期管理流程,如果每个组件都手动处理,效率低下。
Lifecycle 解决了这个问题,它提供了一种标准化的方式来绑定和管理生命周期。
五、Lifecycle 源码实现
1. Lifecycle 抽象类
Lifecycle 定义了具有生命周期的对象。Fragment 与 FragmentActivity 实现了 LifecycleOwner 接口,该接口有 getLifecycle 方法以访问 Lifecycle。开发者可以通过实现 LifecycleOwner 接口来自定义自己的生命周期组件。
addObserver(LifecycleObserver):添加观察者。
removeObserver(LifecycleObserver):移除观察者。
getCurrentState():获取当前状态。
public abstract class Lifecycle {
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
@MainThread
@NonNull
public abstract State getCurrentState();
public enum Event {
ON_CREATE, ON_START, ON_PAUSE, ON_STOP, ON_DESTROY, ON_ANY;
}
public enum State {
DESTROYED, INITIALIZED, CREATED, STARTED, RESUMED;
}
}
Lifecycle 相当于一个中转站,管理生命周期的组件。当状态流转时,中转站内的组件的生命周期状态应保持对应。
2. LifecycleRegistry 实现类
Lifecycle 的具体实现类是 LifecycleRegistry,用来处理多个 LifecycleObserver 的状态。除了 Fragment 与 Activity 以外,还可以处理自定义的生命周期组件。
FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap:将观察者连同状态一起保存起来。
State mState:当前的状态。
WeakReference<LifecycleOwner> mLifecycleOwner:引用持用了生命周期的组件。
关键方法 moveToState 负责处理状态变更:
private void moveToState(State next) {
if (mState == next) return;
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
sync() 方法确保所有观察者的状态与宿主状态同步。它会比较当前状态与最新、最旧观察者的状态,如果不一致,则调用 forwardPass(向前推进)或 backwardPass(向后回退)。
private void sync() {
while (!isSynced()) {
mNewEventOccurred = false;
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
} else {
forwardPass(lifecycleOwner);
}
}
}
dispatchEvent 方法最终通知所有的观察者,继承自 LifecycleObserver 的 LifecycleEventObserver 接口方法 onStateChanged 完成状态的更新操作。
3. LifecycleOwner 接口
LifecycleOwner 是一个接口,仅仅包含了一个方法:返回'生命周期'Lifecycle。
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
以 AppCompatActivity 为例,其完整的继承链路为:AppCompatActivity -> FragmentActivity -> ComponentActivity。
在 ComponentActivity 中,只有一个生命周期方法 onCreate() 作了处理,其他的生命周期方法并未有具体实现。这是通过 ReportFragment 注入来实现的。
4. ReportFragment 注入机制
ReportFragment 是关键代码实现。它通过注入的方式依附到 Activity 之上,将自身的生命周期与 Activity 绑定,也即是将生命周期的管理后移。
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
}
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
}
ReportFragment 通过注入的方法,依附到 Activity 之上,根据 Fragment 特性,此时 Fragment 的生命周期就与宿主 Activity 绑定了。对宿主 Activity 的生命周期的管理自然的就后移到了 Fragment 之上也就是 ReportFragment 中。而最终都回调到了 dispatch() 之中,到这里就完成了分发的工作,那么由谁来真正处理呢?((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); 之前提到接口 Lifecycle 的实现类 LifecycleRegistry 则是完成了对生命周期的处理。
六、使用示例与最佳实践
1. 默认生命周期观察者
官方比较推荐的做法是实现 DefaultLifecycleObserver 接口,这样可以分别处理不同生命周期事件。
class MyObserver : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
}
override fun onPause(owner: LifecycleOwner) {
}
override fun onDestroy(owner: LifecycleOwner) {
}
}
myLifecycleOwner.getLifecycle().addObserver(MyObserver())
2. 自定义生命周期感知类
当然也可以配合 LifecycleRegistry 与 LifecycleOwner 实现更加细致的功能需求,例如在非 Activity/Fragment 组件中模拟生命周期。
class MyActivity : Activity(), LifecycleOwner {
private lateinit var lifecycleRegistry: LifecycleRegistry
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleRegistry = LifecycleRegistry(this)
lifecycleRegistry.markState(Lifecycle.State.CREATED)
}
override fun onStart() {
super.onStart()
lifecycleRegistry.markState(Lifecycle.State.STARTED)
}
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
}
3. 常见陷阱与注意事项
- 线程安全:Lifecycle 的事件分发通常在主线程进行,但在某些异步场景下需要注意线程切换。LifecycleRegistry 内部使用了 FastSafeIterableMap 来处理并发修改。
- 观察者注册时机:建议在 onCreate 之后注册观察者,避免在初始化过程中触发不必要的事件。
- 内存泄漏:务必在 onDestroy 或适当时机移除观察者,防止持有 Activity 上下文导致泄漏。
- 状态一致性:确保 LifecycleOwner 的状态流转符合规范,不要随意跳跃状态(如直接从 CREATED 跳到 RESUMED)。
七、总结
Lifecycle 机制通过观察者模式,将生命周期事件的分发与业务逻辑解耦。ReportFragment 的注入巧妙利用了 Fragment 的生命周期来代理 Activity 的生命周期事件,确保了底层实现的透明性。理解 Lifecycle 的源码实现,特别是 LifecycleRegistry 的 sync 机制和状态流转逻辑,对于编写健壮的 Android 应用至关重要。在实际开发中,应充分利用 Lifecycle 提供的 API,结合 ViewModel 和 LiveData,构建响应式、低耦合的应用架构。
八、参考资料
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online