1. 生命周期概念与核心接口

Android 组件的生命周期管理是构建稳定、高效应用的基础。传统上,开发者需要在 Activity 或 Fragment 的回调方法(如 onCreate()、onDestroy())中手动管理依赖组件的创建与销毁,这极易导致内存泄漏、空指针异常以及代码耦合度过高的问题。Jetpack Lifecycle 库通过引入一套标准化的观察者模式,将生命周期状态与组件行为解耦,使开发者能够以声明式的方式响应生命周期变化。

1.1 核心概念:生命周期状态机

Lifecycle 库将 Android 组件的生命周期抽象为两个枚举:Event(事件)与 State(状态)。State 代表组件当前所处的生命周期阶段(如 CREATED、STARTED),而 Event 代表导致状态转换的触发动作(如 ON_START、ON_STOP)。二者构成一个有限状态机模型:

State对应生命周期阶段进入该状态的事件
DESTROYED组件已销毁ON_DESTROY
INITIALIZED组件已初始化,但未调用 onCreate—
CREATEDonCreate 已调用 / onDestroy 尚未调用ON_CREATE
STARTEDonStart 已调用 / onStop 尚未调用ON_START
RESUMEDonResume 已调用(前台可见且可交互)ON_RESUME

事件的触发顺序严格遵循 Android 原生生命周期:ON_CREATE → ON_START → ON_RESUME → ON_PAUSE → ON_STOP → ON_DESTROY。Lifecycle 对象内部维护着当前 State,并向下游订阅的 LifecycleObserver 分发事件。

1.2 三大核心接口角色

Lifecycle 库围绕三个核心接口构建观察者模式:

  • Lifecycle:持有状态机并管理观察者的注册与事件分发。它是一个抽象类,核心方法包括 addObserver()、removeObserver() 以及 getCurrentState()。
  • LifecycleOwner:拥有 Lifecycle 对象的接口,通常由 Activity、Fragment 或自定义组件实现。只需返回一个 Lifecycle 实例即可。
  • LifecycleObserver:观察者标记接口,通常配合注解 @OnLifecycleEvent 使用,监听特定生命周期事件。
架构要点: LifecycleOwner 提供生命周期数据源,Lifecycle 负责管理状态和事件分发,LifecycleObserver 消费事件。三者组合实现了观察者模式的标准解耦:生产者(Owner)不关心谁在监听,消费者(Observer)不依赖 Owner 的具体实现。

1.3 @OnLifecycleEvent 注解与默认实现

在 androidx.lifecycle 包中,LifecycleObserver 是一个空接口。通过 @OnLifecycleEvent 注解标记方法,并指定要监听的事件类型,Lifecycle 库会在适当事件发生时通过反射调用该方法。示例:

public class MyObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
        // 组件进入前台可见状态时的业务逻辑
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
        // 组件进入不可见状态时的清理逻辑
    }
}
命名习惯: 建议方法名使用 like-onXXXX 模式,与 Android 原生回调格式保持一致(如 onStart、onStop),便于团队阅读和理解事件关联。

1.4 自定义 LifecycleOwner 实现步骤

当自定义组件(如自定义 View、Service 或 Application 子类)需要对外提供生命周期感知能力时,可以手动实现 LifecycleOwner 接口。标准实现流程包含 4 个步骤:

  1. 创建 LifecycleRegistry 实例:在构造器或初始化阶段通过 new LifecycleRegistry(this) 创建状态机对象,并将其赋值给接口方法所需返回的 Lifecycle 对象。
  2. 实现 getLifecycle() 方法:直接返回第一步创建的 LifecycleRegistry 实例。
  3. 在关键生命周期点调 setCurrentState():在自定义组件发生状态变化时(如构建完成、可见/不可见、销毁前),调用 mLifecycleRegistry.setCurrentState(State.XXX),Lifecycle 会自动推导并分发对应事件。
  4. 在销毁时标记 destroy:当组件进入不可逆的销毁阶段时,调用 setCurrentState(State.DESTROYED),通知所有观察者执行清理逻辑。

以下是一个完整的自定义 View 生命周期实现示例:

public class LifecycleAwareView extends View implements LifecycleOwner {
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    public LifecycleAwareView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 构造完成后,手动设置初始状态
        mLifecycleRegistry.setCurrentState(State.INITIALIZED);
    }

    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

    // 假设在 View 的 onAttachedToWindow 和 onDetachedFromWindow 中模拟生命周期
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        // 将状态提升至 STARTED(隐含先触发 ON_CREATE,再自动触发 ON_START)
        mLifecycleRegistry.setCurrentState(State.STARTED);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        // 组件即将销毁,通知观察者
        mLifecycleRegistry.setCurrentState(State.DESTROYED);
    }
}
常见错误: 忘记调用 setCurrentState(State.INITIALIZED) 或 setCurrentState(State.DESTROYED) 会导致观察者永远收不到初始/销毁事件,从而引发资源泄漏。另外,多次调用 setCurrentState() 必须遵循状态机的单向迁移顺序,否则会抛出 IllegalStateException。

1.5 生命周期交互流程

下图展示了 LifecycleOwner、Lifecycle 和 LifecycleObserver 三者之间的运行时交互关系:

Lifecycle 运行时交互流程 LifecycleOwner getLifecycle() 持有 LifecycleRegistry Lifecycle addObserver() setCurrentState() 事件 → 推导状态 LifecycleObserver @OnLifecycleEvent onResume() onPause() 注册 分发事件 状态机流转(State 迁移顺序) 1. DESTROYED → INITIALIZED (组件创建) 2. INITIALIZED → CREATED → STARTED (生命周期上升) 3. STARTED → RESUMED (前台可见且可交互) 4. RESUMED → STARTED → CREATED → DESTROYED (生命周期下降) ※ LifecycleRegistry 在 setCurrentState 时自动推导缺失事件,并按照顺序分发

1.6 调试与验证

观察者是否收到预期事件可以通过加入日志进行验证。在 @OnLifecycleEvent 方法中添加日志输出:

@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void onCreate() {
    Log.d("LifecycleDemo", "Observer received ON_CREATE");
}

若日志未输出或输出顺序异常,应首先检查 LifecycleOwner 是否在正确的时机调用了 setCurrentState(),以及是否在 getLifecycle() 中返回了正确的 LifecycleRegistry 实例。也可以调用 LifecycleRegistry.currentState 的 getter 获取当前状态,验证状态机是否处于预期阶段。