Android Lifecycle 使用

一、如何使用 Lifecycle

1. 基本观察者注册

观察者注册的三种方式

方式 实现 优势 注意
接口回调 (推荐) 实现 DefaultLifecycleObserver 接口 编译时安全,无反射 Java 8 支持
统一事件回调 实现 LifecycleEventObserver 接口 事件统一处理,灵活 需手动判断事件类型
注解方式 (已废弃) @OnLifecycleEvent(Lifecycle.Event.ON_XXX) 兼容旧代码 性能低,官方废弃

Lifecycle 的核心是 观察生命周期状态变化,支持两种主流方式:

方式1:接口回调(推荐,无反射)

kotlin 复制代码
class MyObserver : DefaultLifecycleObserver {
    override fun onCreate(owner: LifecycleOwner) {
        Log.d("Lifecycle", "onCreate")
    }
    override fun onDestroy(owner: LifecycleOwner) {
        Log.d("Lifecycle", "onDestroy")
    }
}

// 注册观察者
lifecycle.addObserver(MyObserver())

方式2:注解方式(已废弃,仅兼容旧代码)

kotlin 复制代码
class LegacyObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun connect() {
        Log.d("Lifecycle", "Resumed and connected")
    }
}

注意 :AndroidX 已废弃注解方式,推荐使用 DefaultLifecycleObserver


2. 自定义 LifecycleOwner

任何类都可以通过实现 LifecycleOwner 提供生命周期:

kotlin 复制代码
class CustomController : LifecycleOwner {
    private val lifecycleRegistry = LifecycleRegistry(this)

    fun start() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
    }

    override fun getLifecycle(): Lifecycle = lifecycleRegistry
}

// 使用
val controller = CustomController()
controller.lifecycle.addObserver(MyObserver())
controller.start() // 触发ON_START事件

应用场景:View 生命周期管理、Service 生命周期封装

二、扩展应用:Lifecycle 的高级用法

1.协程生命周期绑定

scss 复制代码
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        // 仅在STARTED及以上状态执行
        fetchData() // 离开STARTED自动取消
    }
}

优势:避免后台任务资源浪费

2. 全局应用生命周期监听

kotlin 复制代码
// 监听整个应用的前后台切换
ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
    override fun onStart(owner: LifecycleOwner) {
        Log.d("App", "进入前台")
    }
    override fun onStop(owner: LifecycleOwner) {
        Log.d("App", "退到后台")
    }
})

3. 避免内存泄漏的最佳实践

kotlin 复制代码
class SafeResourceObserver : DefaultLifecycleObserver {
    private val weakView = WeakReference(view)

    override fun onDestroy(owner: LifecycleOwner) {
        weakView.get()?.releaseResources() // 弱引用防泄漏
        owner.lifecycle.removeObserver(this) // 自动解绑
    }
}

4.多模块生命周期管理

假设一个 Activity 中需要集成多个独立模块(如 视频播放器数据统计广告SDK ),每个模块都需要监听 Activity 的生命周期(如 onResume/onPause)。传统实现方式会导致以下问题:

  1. 代码耦合:每个模块直接依赖 Activity,修改生命周期逻辑需改动多处。
  2. 重复注册 :每个模块单独调用 lifecycle.addObserver(),冗余代码。
  3. 维护困难:新增或移除模块时需修改 Activity 代码

自定义 LifecycleOwner 统一分发

核心思想

  • 创建一个中介者 (如 CompositeLifecycleOwner),它聚合多个子组件的生命周期事件。
  • 子模块只需监听中介者,无需知道真正的 Activity/Fragment。
kotlin 复制代码
/**
 * 统一管理多个子组件的 LifecycleOwner
 */
class CompositeLifecycleOwner : LifecycleOwner {
    private val lifecycleRegistry = LifecycleRegistry(this)
    private val childOwners = mutableListOf<LifecycleOwner>()

    // 添加子组件(如Activity/Fragment)
    fun attachChild(child: LifecycleOwner) {
        if (childOwners.contains(child)) return
        
        child.lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onStart(owner: LifecycleOwner) {
                if (lifecycleRegistry.currentState.isAtLeast(Lifecycle.State.STARTED)) return
                lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
            }
            override fun onStop(owner: LifecycleOwner) {
                lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
            }
            // 其他事件同理...
        })
        childOwners.add(child)
    }

    override fun getLifecycle(): Lifecycle = lifecycleRegistry
}

// ---------- 使用示例 ----------
class VideoPlayerModule(private val lifecycle: Lifecycle) {
    init {
        lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onStart(owner: LifecycleOwner) {
                startBuffering()
            }
            override fun onStop(owner: LifecycleOwner) {
                pausePlayback()
            }
        })
    }
}

class AnalyticsModule(private val lifecycle: Lifecycle) {
    init {
        lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onResume(owner: LifecycleOwner) {
                trackScreenView()
            }
        })
    }
}

// 在Activity中统一注册
class MainActivity : AppCompatActivity() {
    private val compositeOwner = CompositeLifecycleOwner()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 将Activity的生命周期委托给compositeOwner
        compositeOwner.attachChild(this) 
        
        // 各模块只需依赖compositeOwner
        VideoPlayerModule(compositeOwner.lifecycle)
        AnalyticsModule(compositeOwner.lifecycle)
    }
}
相关推荐
JuneXcy12 分钟前
11.Layout-Pinia优化重复请求
前端·javascript·css
子洋22 分钟前
快速目录跳转工具 zoxide 使用指南
前端·后端·shell
天下无贼!23 分钟前
【自制组件库】从零到一实现属于自己的 Vue3 组件库!!!
前端·javascript·vue.js·ui·架构·scss
CF14年老兵43 分钟前
✅ Next.js 渲染速查表
前端·react.js·next.js
司宸1 小时前
学习笔记八 —— 虚拟DOM diff算法 fiber原理
前端
阳树阳树1 小时前
JSON.parse 与 JSON.stringify 可能引发的问题
前端
让辣条自由翱翔1 小时前
总结一下Vue的组件通信
前端
dyb1 小时前
开箱即用的Next.js SSR企业级开发模板
前端·react.js·next.js
前端的日常1 小时前
Vite 如何处理静态资源?
前端
前端的日常1 小时前
如何在 Vite 中配置路由?
前端