2. 生命周期状态机核心原理:CREATED、STARTED、RESUMED 与事件流转

Android 的 Lifecycle 组件将 Activity/Fragment 原有的生命周期回调抽象为一台有限状态机。状态(State)与事件(Event)构成自动机双要素:状态表示组件当前所处的生命周期阶段,事件驱动状态发生迁移。理解状态机的内在流转,是设计感知型组件的基础。

2.1 状态定义与事件清单

在 android.arch.lifecycle.Lifecycle 中定义了 5 个状态(State)和 6 个事件(Event)。所有自定义观察者通过监听事件的变化来同步自身逻辑。

状态描述对应 Activity 阶段
INITIALIZED组件已构造,但未被添加至窗口管理器构造函数后、onCreate 前
CREATED组件已创建,但未开始对用户可见onCreate 调用后 / onStop 调用后
STARTED组件对用户可见,但不在前台交互onStart 调用后 / onPause 调用后
RESUMED组件在前台且可交互onResume 调用后
DESTROYED组件已被销毁,不再可用onDestroy 调用后
事件触发时机迁移前状态 → 迁移后状态
ON_CREATE组件进入 CREATEDINITIALIZED → CREATED
ON_START组件进入 STARTEDCREATED → STARTED
ON_RESUME组件进入 RESUMEDSTARTED → RESUMED
ON_PAUSE组件退出 RESUMEDRESUMED → STARTED
ON_STOP组件退出 STARTEDSTARTED → CREATED
ON_DESTROY组件进入 DESTROYEDCREATED → DESTROYED

2.2 状态流转模型

状态机的核心是两个闭环:前向推进(INITIALIZED → CREATED → STARTED → RESUMED)与后向回退(RESUMED → STARTED → CREATED → DESTROYED)。LifecycleRegistry 负责在事件发生时原子性地更新当前状态,并遍历所有注册的观察者,按“状态从小到大的顺序”通知。

关键原则:状态只能单向递增(向前)或单向递减(向后),不允许跳状态。例如,不能从 CREATED 直接到 RESUMED,必须经过 STARTED。
生命周期状态机流转图 Lifecycle 状态机:状态 & 事件流转 INITIALIZED CREATED STARTED RESUMED DESTROYED ON_CREATE ON_START ON_RESUME ON_PAUSE ON_STOP ON_DESTROY 状态流特点 前向推进:INIT→CRE→STA→RES 回退:RES→STA→CRE→DES

2.3 观察者如何感知状态变化

自定义组件通过实现 LifecycleObserver 并注册到 LifecycleOwner 中。当状态改变时,LifecycleRegistry 会遍历所有观察者,按以下顺序调用对应注解方法:

@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onStart() { /* 组件对用户可见 */ }

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onStop() { /* 组件不再可见,释放资源 */ }

在 Lifecycle 内部,状态比较使用 compareTo 确保观察者不会被重复通知,也不会错过中间状态。例如,若当前状态为 RESUMED,新注册的观察者会立刻收到 ON_CREATE、ON_START、ON_RESUME 三件套事件,使其与当前状态同步。

常见错误:在 ON_CREATE 回调中启动一个长时间运行的动画;或在 ON_DESTROY 时尝试访问已经销毁的 Context。状态机要求观察者必须能够正确处理每一次事件,不允许假设调用顺序。

2.4 代码示例:实现感知型位置监听器

以下示例展示一个位置监听器如何依赖生命周期状态,以避免内存泄漏和冗余更新:

public class LocationLifecycleObserver implements LifecycleObserver {

    private final LocationManager locationManager;
    private final LocationListener listener;

    public LocationLifecycleObserver(Context context, LocationListener listener) {
        this.locationManager =
            (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        this.listener = listener;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void startUpdates() {
        locationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER,
            5000L, 0f, listener);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void stopUpdates() {
        locationManager.removeUpdates(listener);
    }
}

在 Activity 中注册:

LocationLifecycleObserver observer =
    new LocationLifecycleObserver(this, myListener);
getLifecycle().addObserver(observer);

当 Activity 进入前台(ON_START → ON_RESUME)时自动启动定位,后台(ON_PAUSE → ON_STOP)时自动停止,无需手动干预。

2.5 状态机调试方法

通过 LifecycleRegistry 的调试日志可观察状态变化。在 Application 或 Activity 中启用日志:

LifecycleRegistry registry = (LifecycleRegistry) getLifecycle();
registry.setCurrentState(Lifecycle.State.CREATED); // 手动触发(仅开发场景)

更推荐使用 Android Studio 的 Lifecycle Inspector(Android Studio 4.2+):运行应用后,在 Profiler 中选择 Lifecycle 选项卡,即可实时查看每个 LifecycleOwner 的当前状态和事件历史。

调试技巧:在自定义 Observer 的 onStateChanged 方法内输出日志,对比预期状态与实际状态。常见问题解决思路:
  • 注册后未收到回调 → 检查是否在 onCreate 之前调用了 addObserver(应确保 owner 已初始化)。
  • 收到重复回调 → 观察者被多次注册,使用 removeObserver 清理。
  • 状态跳转错误 → 确认 Activity/Fragment 没有手动调用 performCreate 等内部方法。

2.6 性能优化要点

场景优化策略原因
Observer 中包含 I/O 操作使用 ViewModel + LiveData 异步处理生命周期回调在主线程,阻塞会导致卡顿
大量 Observer 注册合并观察逻辑,或使用 DefaultLifecycleObserver 避免反射减少遍历开销,提高通知效率
频繁状态回退(如快速切换前后台)Observer 内实现幂等操作(如 start/stop 增加防重复检查)防止资源重复申请/释放
需要跨进程生命周期同步利用 ProcessLifecycleOwner 监听全局前后台避免每个组件独立注册,降低开销

掌握状态机原理后,下一环节将深入 LifecycleRegistry 的源码实现,揭示状态同步与事件分发的内部机制。