一、Lifecycle 的核心原理:状态机与观察者模式

说实话,Lifecycle 是我在 Jetpack 里最先爱上的组件。为什么?因为它解决了一个困扰 Android 开发者多年的老问题——组件生命周期管理混乱。

你想想看,以前我们是怎么管理生命周期的?在 Activity 的 onCreate 里初始化,onDestroy 里释放。如果有个第三方库要监听生命周期,要么写一堆回调接口,要么用 EventBus 满天飞。代码耦合度高得吓人。

Lifecycle 的核心思想其实很简单:把生命周期状态抽象成一个状态机,然后用观察者模式通知订阅者

1.1 状态机:生命周期到底有几个状态?

很多人以为生命周期就是 onCreateonStartonResume 这些回调方法。但 Lifecycle 的抽象更精细。它把生命周期分成了两种概念:状态(State)事件(Event)

  • State:当前组件所处的生命周期阶段。比如 CREATEDSTARTEDRESUMEDDESTROYED
  • Event:状态之间的转换动作。比如 ON_CREATEON_STARTON_RESUMEON_PAUSEON_STOPON_DESTROY

我画了一张状态机流转图,你看一眼就明白了:

Lifecycle 状态机流转图 INITIALIZED CREATED STARTED RESUMED DESTROYED ON_CREATE ON_START ON_RESUME ON_PAUSE ON_STOP ON_DESTROY 正向事件 反向事件

这张图我建议你保存下来。每次写 Lifecycle 相关代码时,对照着看,思路会清晰很多。

1.2 观察者模式:谁在监听谁?

Lifecycle 用了标准的观察者模式。LifecycleOwner 是被观察者,LifecycleObserver 是观察者。当生命周期状态发生变化时,LifecycleOwner 会遍历所有注册的观察者,逐个通知。

核心接口就三个:

// 被观察者:拥有生命周期的组件
public interface LifecycleOwner {
    Lifecycle getLifecycle();
}

// 生命周期抽象类
public abstract class Lifecycle {
    public abstract void addObserver(LifecycleObserver observer);
    public abstract void removeObserver(LifecycleObserver observer);
    public abstract State getCurrentState();
}

// 观察者标记接口
public interface LifecycleObserver {}

嗯,这里要注意:LifecycleObserver 本身是个空接口。真正干活的是它的子接口 DefaultLifecycleObserver 或者注解方式 @OnLifecycleEvent

核心要点:Lifecycle 的观察者模式不是简单的回调,而是基于状态机的增量通知。什么意思?比如当前状态是 STARTED,新注册一个观察者,它会收到 ON_CREATE 事件,而不是直接跳到当前状态。这保证了观察者能完整感知生命周期的变化过程。

二、LifecycleOwner 与 LifecycleObserver 的绑定机制

绑定过程,说白了就是「观察者注册」和「事件分发」两个步骤。我拆开来讲。

2.1 注册过程:addObserver 干了什么?

当你调用 lifecycle.addObserver(observer) 时,内部做了三件事:

  1. 包装观察者:把 LifecycleObserver 包装成 ObserverWithState,里面存了观察者的注解方法和当前状态。
  2. 状态同步:如果当前生命周期状态已经大于 INITIALIZED,会从 ON_CREATE 开始,把缺失的事件逐个补发。
  3. 存储引用:把包装后的对象存入 FastSafeIterableMap,保证遍历时的线程安全。

我贴一段简化后的源码,你感受一下:

// LifecycleRegistry.java (简化版)
public void addObserver(LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    
    // 存入 map
    mObserverMap.putIfAbsent(observer, statefulObserver);
    
    // 状态同步:补发缺失的事件
    while (statefulObserver.mState.compareTo(mState) < 0 
           && mObserverMap.contains(observer)) {
        Event event = Event.upFrom(statefulObserver.mState);
        if (event == null) break;
        statefulObserver.dispatchEvent(this, event);
    }
}

我在项目中遇到过一个问题:在 onResume 里注册观察者,结果 onCreate 事件没收到。后来看了源码才明白——addObserver 会补发事件,但补发是从 INITIALIZED 开始往上推的。所以即使你在 onResume 注册,也能收到 ON_CREATEON_START。这个设计很巧妙,对吧?

2.2 事件分发:状态变更时发生了什么?

当 Activity 执行 onStart 时,ReportFragment 会调用 lifecycle.handleLifecycleEvent(ON_START)。内部逻辑是这样的:

// LifecycleRegistry.java
public void handleLifecycleEvent(Event event) {
    State next = getStateAfter(event);
    moveToState(next);
}

private void moveToState(State next) {
    mState = next;
    // 遍历所有观察者,逐个分发事件
    sync();
}

sync() 方法会遍历 mObserverMap,对每个观察者调用 dispatchEvent。如果观察者实现了 DefaultLifecycleObserver,就调用对应的回调方法;如果是注解方式,就用反射调用。

性能提示DefaultLifecycleObserver 是 Java 8 接口,用 default 方法实现,没有反射开销。而 @OnLifecycleEvent 注解方式依赖反射,性能略差。我个人习惯在新项目里全部用 DefaultLifecycleObserver

三、自定义 LifecycleOwner 实战

有时候我们需要让自定义类也拥有生命周期管理能力。比如一个自定义 View,或者一个后台服务。怎么做?实现 LifecycleOwner 接口,然后用 LifecycleRegistry 管理状态。

3.1 一个完整的自定义 LifecycleOwner 示例

假设我们有一个 TimerManager,需要管理定时器的生命周期:

class TimerManager : LifecycleOwner {
    private val lifecycleRegistry = LifecycleRegistry(this)
    
    override fun getLifecycle(): Lifecycle = lifecycleRegistry
    
    fun start() {
        // 模拟生命周期变化
        lifecycleRegistry.currentState = Lifecycle.State.STARTED
        // 开始定时器...
    }
    
    fun stop() {
        // 停止定时器...
        lifecycleRegistry.currentState = Lifecycle.State.CREATED
    }
    
    fun destroy() {
        lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
    }
}

使用的时候:

val timerManager = TimerManager()
timerManager.lifecycle.addObserver(object : DefaultLifecycleObserver {
    override fun onStart(owner: LifecycleOwner) {
        println("定时器启动了")
    }
    
    override fun onDestroy(owner: LifecycleOwner) {
        println("定时器销毁了,释放资源")
    }
})

timerManager.start()
// 业务逻辑...
timerManager.destroy()

注意LifecycleRegistry 不是线程安全的。如果你在多线程环境下调用 setCurrentState,需要自己加锁。我曾经在协程里直接调用,结果遇到了并发修改异常。后来用 synchronized 包了一层才解决。

3.2 什么时候需要自定义 LifecycleOwner?

我总结了三个典型场景:

  • 自定义 View:比如一个视频播放器 View,需要根据页面生命周期暂停/恢复播放。
  • 后台 Service:比如定位服务,需要在 Activity 销毁时自动停止定位。
  • 测试环境:单元测试中模拟生命周期变化,验证观察者行为。

四、在 ViewModel 中优雅管理生命周期

ViewModel 本身就是一个 LifecycleOwner,但它的生命周期和 Activity/Fragment 不同。ViewModel 的生命周期是「从创建到页面销毁」,不受屏幕旋转等配置变更影响。

4.1 ViewModel 的生命周期范围

看这张对比表就清楚了:

组件 生命周期范围 典型场景
Activity onCreate ~ onDestroy 屏幕旋转会重建
Fragment onAttach ~ onDetach 随 Fragment 生命周期
ViewModel 创建 ~ 页面彻底销毁 屏幕旋转不重建

ViewModel 的 onCleared() 方法会在页面彻底销毁时调用。我习惯在这里释放一些重量级资源,比如网络请求的协程 Job。

4.2 在 ViewModel 中使用 Lifecycle

ViewModel 本身不直接持有 Activity 的 Lifecycle,但我们可以通过 SavedStateHandle 或者 ProcessLifecycleOwner 来感知应用级别的生命周期。

举个例子,我想在 App 进入后台时暂停数据刷新,回到前台时恢复:

class DataRefreshViewModel : ViewModel() {
    private val refreshJob = SupervisorJob()
    private val scope = CoroutineScope(refreshJob + Dispatchers.IO)
    
    init {
        // 监听应用前后台切换
        ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onStart(owner: LifecycleOwner) {
                startRefreshing()
            }
            
            override fun onStop(owner: LifecycleOwner) {
                stopRefreshing()
            }
        })
    }
    
    private fun startRefreshing() {
        scope.launch {
            while (isActive) {
                // 刷新数据
                delay(30_000)
            }
        }
    }
    
    private fun stopRefreshing() {
        refreshJob.cancelChildren()
    }
    
    override fun onCleared() {
        super.onCleared()
        refreshJob.cancel()
    }
}

最佳实践:ViewModel 里不要直接持有 Activity 或 Fragment 的引用,否则会导致内存泄漏。用 ProcessLifecycleOwner 或者 LiveData 来间接感知生命周期,才是正道。

4.3 避坑指南:我曾经踩过的坑

我曾经在 ViewModel 里直接调用了 lifecycle.addObserver(),结果发现 ViewModel 的 lifecycle 属性返回的是 LifecycleRegistry,但它的状态始终是 CREATED,不会自动变化。后来才意识到——ViewModel 的 Lifecycle 需要手动管理,不像 Activity 那样有系统自动驱动。

正确的做法是:如果 ViewModel 需要感知 Activity 的生命周期,通过 LiveData 或者 Flow 把生命周期事件传递进来,而不是直接依赖 ViewModel 自身的 Lifecycle。

嗯,关于 Lifecycle 的核心内容,今天就聊到这里。这个组件看似简单,但用好了能让你的代码结构清晰很多。记住一句话:让生命周期管理回归组件本身,而不是散落在各个回调里


公众号:蓝海资料掘金营,微信deep3321