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)
    }
}
相关推荐
疯狂的沙粒13 分钟前
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
前端·uni-app·html
小妖66617 分钟前
html 滚动条滚动过快会留下边框线
前端·html
heroboyluck31 分钟前
Svelte 核心语法详解:Vue/React 开发者如何快速上手?
前端·svelte
海的诗篇_33 分钟前
前端开发面试题总结-JavaScript篇(二)
开发语言·前端·javascript·typescript
琹箐43 分钟前
ant-design4.xx实现数字输入框; 某些输入法数字需要连续输入两次才显示
前端·javascript·anti-design-vue
程序员-小李44 分钟前
VuePress完美整合Toast消息提示
前端·javascript·vue.js
Uyker2 小时前
从零开始制作小程序简单概述
前端·微信小程序·小程序
EndingCoder6 小时前
React从基础入门到高级实战:React 实战项目 - 项目三:实时聊天应用
前端·react.js·架构·前端框架
阿阳微客7 小时前
Steam 搬砖项目深度拆解:从抵触到真香的转型之路
前端·笔记·学习·游戏
德育处主任Pro7 小时前
『React』Fragment的用法及简写形式
前端·javascript·react.js