2、Lifecycle:Lifecycle原理、LifecycleObserver、ProcessLifecycleOwner实战

说实话,Lifecycle 是我在 Jetpack 里最早爱上的组件。为什么?因为它解决了一个让我头疼很久的问题——生命周期管理。

你想想看,以前我们写 Android 代码,Activity 和 Fragment 的生命周期回调里,到处都是初始化、释放资源的代码。一个 onDestroy 里可能塞了七八个清理操作,稍不留神就漏掉一个,然后内存泄漏就找上门了。

Lifecycle 这个组件,说白了就是帮我们把「生命周期感知」这件事标准化了。它让任何类都能感知到 Activity 或 Fragment 的生死,而不需要自己手动去监听。

2.1 Lifecycle 的核心原理

Lifecycle 的原理其实不复杂。它内部维护了一个状态机,用两个枚举来管理生命周期:

  • Event:生命周期事件,比如 ON_CREATE、ON_START、ON_RESUME 等
  • State:当前生命周期状态,比如 CREATED、STARTED、RESUMED 等

我刚开始看源码的时候,觉得这俩东西有点绕。后来我画了个图,一下就明白了:

Lifecycle 状态机流转图 INITIALIZED CREATED STARTED RESUMED DESTROYED ON_CREATE ON_START ON_RESUME ON_PAUSE ON_STOP ON_DESTROY 前进事件 后退事件 销毁事件

看到没?状态是「当前在哪」,事件是「要去哪」。LifecycleOwner 发出事件,LifecycleObserver 收到事件后做出响应。整个流程是观察者模式的一个经典应用。

核心要点:Lifecycle 使用「状态 + 事件」的双重机制,确保观察者能准确感知生命周期变化。状态是结果,事件是过程。

2.2 LifecycleObserver 实战

好了,原理讲完了,咱们直接上代码。我个人习惯把 LifecycleObserver 写成内部类或者单独的文件,看场景而定。

先来个最简单的例子:

class MyObserver : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume() {
        Log.d("MyObserver", "Activity 恢复了,开始干活")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        Log.d("MyObserver", "Activity 暂停了,暂停工作")
    }
}

// 在 Activity 中绑定
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycle.addObserver(MyObserver())
    }
}

嗯,这里要注意一点。从 API 29 开始,@OnLifecycleEvent 注解被标记为弃用了。Google 推荐用 DefaultLifecycleObserver 接口。我建议新项目直接用新方式:

class MyObserver : DefaultLifecycleObserver {

    override fun onResume(owner: LifecycleOwner) {
        Log.d("MyObserver", "使用新接口,更安全")
    }

    override fun onPause(owner: LifecycleOwner) {
        Log.d("MyObserver", "暂停了")
    }
}

为什么推荐新接口?因为注解方式用的是反射,性能上有一丢丢损耗。虽然微乎其微,但能避免就避免,对吧?

我的建议:新项目一律用 DefaultLifecycleObserver。老项目如果还在用注解,也不用急着改,不影响功能。

2.3 实战场景:定位监听器

我在项目中遇到过这样一个场景:需要在 Activity 可见时持续获取定位,不可见时停止定位。用 LifecycleObserver 实现起来特别优雅:

class LocationObserver(
    private val context: Context
) : DefaultLifecycleObserver {

    private val locationManager = 
        context.getSystemService(Context.LOCATION_SERVICE) as LocationManager

    override fun onStart(owner: LifecycleOwner) {
        // 开始定位
        locationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER,
            5000L,
            10f,
            locationListener
        )
    }

    override fun onStop(owner: LifecycleOwner) {
        // 停止定位,省电又安全
        locationManager.removeUpdates(locationListener)
    }

    private val locationListener = LocationListener { location ->
        Log.d("Location", "纬度: ${location.latitude}, 经度: ${location.longitude}")
    }
}

你看,这样写的好处是:定位的开启和关闭完全由生命周期驱动,开发者不需要在 Activity 里手动管理。代码的职责划分非常清晰。

2.4 ProcessLifecycleOwner 实战

ProcessLifecycleOwner 是个好东西。它监听的是整个 App 的前后台切换,而不是单个 Activity。

我曾经踩过一个坑:想在 App 切到后台时做一些清理工作,但不知道该监听哪个 Activity。后来发现 ProcessLifecycleOwner 就是干这个的。

使用前记得在 build.gradle 里加依赖:

implementation "androidx.lifecycle:lifecycle-process:2.6.2"

然后写个观察者:

class AppLifecycleObserver : DefaultLifecycleObserver {

    override fun onStart(owner: LifecycleOwner) {
        Log.d("AppLifecycle", "App 进入前台")
        // 比如:重新连接 WebSocket
    }

    override fun onStop(owner: LifecycleOwner) {
        Log.d("AppLifecycle", "App 进入后台")
        // 比如:保存草稿、释放内存
    }
}

// 在 Application 中注册
class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle
            .addObserver(AppLifecycleObserver())
    }
}

注意:ProcessLifecycleOwner 的 onStart 和 onStop 对应的是「至少有一个 Activity 可见」和「所有 Activity 都不可见」。它不感知单个 Activity 的创建和销毁。

2.5 避坑指南

我总结几个实际开发中容易踩的坑:

  • 不要在 onDestroy 里做耗时操作——系统可能不等你执行完就杀进程了
  • 多个 Observer 的执行顺序不保证——别依赖顺序逻辑
  • Fragment 的 Lifecycle 和 Activity 不同步——Fragment 有自己的生命周期,别搞混了

我曾经在项目里犯过一个错:在 Fragment 的 Observer 里直接操作 Activity 的 View,结果 Fragment 已经销毁了,View 也空了,直接空指针。后来我养成了一个习惯:在 Observer 里先检查 Lifecycle 的当前状态,再做操作。

override fun onResume(owner: LifecycleOwner) {
    if (owner.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
        // 安全了,可以操作 UI
        updateUI()
    }
}

这个小习惯,帮我避免了好几次线上崩溃。

2.6 总结一下

Lifecycle 这个组件,说白了就是让「生命周期感知」变得简单、标准化。它的核心价值在于:

场景 传统做法 Lifecycle 做法
定位管理 在 onResume/onPause 里手动开关 Observer 自动管理
App 前后台 监听所有 Activity 的生命周期 ProcessLifecycleOwner 一行搞定
资源释放 在 onDestroy 里写一堆清理代码 Observer 自动释放

我个人觉得,Lifecycle 是 Jetpack 里最值得优先学习的组件。因为它解决的是最基础、最普遍的问题。而且,后面要学的 LiveData、ViewModel 都建立在它的基础之上。把 Lifecycle 搞懂了,后面的路就好走了。

好了,这一章就到这里。代码不多,但都是实战中提炼出来的经验。你可以在自己的项目里试试,感受一下「生命周期感知」带来的清爽感。


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