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)
    }
}
相关推荐
1024肥宅10 分钟前
现代 JavaScript 特性:TypeScript 深度解析与实践
前端·javascript·typescript
用户479492835691520 分钟前
并发编程里的"堵车"与"红绿灯":死锁、活锁与两种锁策略(乐观锁、悲观锁)
前端·后端
一 乐21 分钟前
智慧医药|基于springboot + vue智慧医药系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端
CC码码38 分钟前
告别杂乱数字:用 Intl.NumberFormat 打造全球友好的前端体验
前端·javascript·面试
妮妮喔妮1 小时前
Webpack和Vite优化的区别
前端·webpack·node.js
广州华水科技1 小时前
单北斗GNSS在大坝形变监测中的应用与性能分析
前端
等风来不如迎风去1 小时前
【web】页面透明、插入图片
前端
谢尔登1 小时前
a 标签的跳转机制
前端·javascript·webpack·node.js
狂炫冰美式1 小时前
当硅基神明撞上人类的“叹息之墙”:距离证明哥德巴赫猜想,AI还有多远?
前端·算法·架构
毕设源码-邱学长2 小时前
【开题答辩全过程】以 基于Vue的爱心公益募捐平台的设计与实现为例,包含答辩的问题和答案
前端·javascript·vue.js