compose中 DisposableEffect和onDispose

跟进 定义 → 关系 → 触发时机 → 正确使用模式 → 常见坑 → MVI 场景 来讲清楚。


一、先给一句话结论

DisposableEffect 是"生命周期作用域"
onDispose 是"离开该作用域时的清理回调"

👉 两者不是同级概念


二、先把概念分清楚(非常重要)

1️⃣ DisposableEffect 是什么?

kotlin 复制代码
DisposableEffect(key) {
    // 初始化 / 注册逻辑

    onDispose {
        // 清理逻辑
    }
}

它本身代表:

"当这个 Composable 进入组合时执行一次,当离开或 key 变化时执行清理"


2️⃣ onDispose 是什么?

kotlin 复制代码
onDispose {
    // 清理资源
}

它只是一个回调函数

"当 DisposableEffect 被销毁时执行"

👉 onDispose 永远只能写在 DisposableEffect 里


三、生命周期触发时机(核心)

我们用一张表直接说明 👇

事件 DisposableEffect onDispose
首次进入组合 执行 effect 代码
普通重组 ❌ 不执行
key 发生变化 ❌(旧的 effect 销毁)
离开组合

👉 onDispose 的触发条件 = effect 生命周期结束


四、一个最直观的时间线(建议你在脑子里记住)

text 复制代码
Composable 进入组合
   ↓
DisposableEffect 执行(注册)
   ↓
多次重组(不影响)
   ↓
Composable 离开组合 / key 改变
   ↓
onDispose 执行(清理)

五、标准使用模式(99% 场景)

✅ 模板写法(直接记)

kotlin 复制代码
DisposableEffect(key) {
    // 1️⃣ 注册 / 初始化
    val resource = registerSomething()

    onDispose {
        // 2️⃣ 注销 / 清理
        unregister(resource)
    }
}

典型场景 1:注册监听

kotlin 复制代码
DisposableEffect(lifecycle) {
    val observer = LifecycleEventObserver { _, event ->
        Log.d("Lifecycle", "$event")
    }
    lifecycle.addObserver(observer)

    onDispose {
        lifecycle.removeObserver(observer)
    }
}

典型场景 2:系统资源(Receiver)

kotlin 复制代码
DisposableEffect(Unit) {
    val receiver = MyReceiver()
    context.registerReceiver(receiver, filter)

    onDispose {
        context.unregisterReceiver(receiver)
    }
}

六、key 的作用(非常关键)

kotlin 复制代码
DisposableEffect(userId) { ... }

行为规则:

  • userId 不变 → effect 一直存在

  • userId 变化 →

    1. 先调用旧的 onDispose
    2. 再执行新的 DisposableEffect

👉 key = 生命周期边界


七、为什么不用 LaunchedEffect 来做这些?

场景 LaunchedEffect DisposableEffect
异步任务
协程自动取消
资源注册释放
同步监听

👉 DisposableEffect 解决的是"资源对称性问题"


八、一个非常常见的反模式(一定要避开)

❌ 错误写法:只注册,不清理

kotlin 复制代码
DisposableEffect(Unit) {
    lifecycle.addObserver(observer)
}

👉 Lint 都会直接报警


❌ 错误写法:在 onDispose 里做初始化

kotlin 复制代码
DisposableEffect(Unit) {
    onDispose {
        initSomething() // ❌
    }
}

九、在 MVI + Compose 中的正确定位

Composable 只负责 UI 生命周期

  • ViewModel:业务生命周期
  • DisposableEffect:UI 资源生命周期

示例:绑定 UI 层事件

kotlin 复制代码
DisposableEffect(Unit) {
    viewModel.bindUi()

    onDispose {
        viewModel.unbindUi()
    }
}

十、再给一句"工程级总结"(很重要)

DisposableEffect 是"声明式生命周期",
onDispose 是"它的 onDestroy 回调"。


相关推荐
stevenzqzq13 小时前
compose中 SideEffect概念以及作用
compose
码农搬砖_202013 小时前
【一站式学会compose】 Android UI体系之 Text的使用和介绍
android·compose
stevenzqzq1 天前
Compose基础入门
开发语言·compose
stevenzqzq2 天前
Compose 实战练习
compose
遇见火星4 天前
Docker Compose 实战教程,理解Docker Compose核心概念,学会编写 compose.yml,掌握常用命令!
运维·docker·容器·compose
csdn12259873368 天前
JetPack Compose 入门先搞清楚
android·compose·jetpack
モンキー・D・小菜鸡儿16 天前
Android Jetpack Compose 基础控件介绍
android·kotlin·android jetpack·compose
hnlgzb1 个月前
androidx.compose.material3哪几个文件是经常用到的?
androidx·compose