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 | 组件进入 CREATED | INITIALIZED → CREATED |
ON_START | 组件进入 STARTED | CREATED → STARTED |
ON_RESUME | 组件进入 RESUMED | STARTED → RESUMED |
ON_PAUSE | 组件退出 RESUMED | RESUMED → STARTED |
ON_STOP | 组件退出 STARTED | STARTED → CREATED |
ON_DESTROY | 组件进入 DESTROYED | CREATED → DESTROYED |
2.2 状态流转模型
状态机的核心是两个闭环:前向推进(INITIALIZED → CREATED → STARTED → RESUMED)与后向回退(RESUMED → STARTED → CREATED → DESTROYED)。LifecycleRegistry 负责在事件发生时原子性地更新当前状态,并遍历所有注册的观察者,按“状态从小到大的顺序”通知。
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 的当前状态和事件历史。
onStateChanged 方法内输出日志,对比预期状态与实际状态。常见问题解决思路:
- 注册后未收到回调 → 检查是否在
onCreate之前调用了addObserver(应确保 owner 已初始化)。 - 收到重复回调 → 观察者被多次注册,使用
removeObserver清理。 - 状态跳转错误 → 确认 Activity/Fragment 没有手动调用
performCreate等内部方法。
2.6 性能优化要点
| 场景 | 优化策略 | 原因 |
|---|---|---|
| Observer 中包含 I/O 操作 | 使用 ViewModel + LiveData 异步处理 | 生命周期回调在主线程,阻塞会导致卡顿 |
| 大量 Observer 注册 | 合并观察逻辑,或使用 DefaultLifecycleObserver 避免反射 | 减少遍历开销,提高通知效率 |
| 频繁状态回退(如快速切换前后台) | Observer 内实现幂等操作(如 start/stop 增加防重复检查) | 防止资源重复申请/释放 |
| 需要跨进程生命周期同步 | 利用 ProcessLifecycleOwner 监听全局前后台 | 避免每个组件独立注册,降低开销 |
掌握状态机原理后,下一环节将深入 LifecycleRegistry 的源码实现,揭示状态同步与事件分发的内部机制。