Compose 全套 Effect / State / Flow 终极思维导图

6 阅读3分钟

一、整体分类总览

1. 重组同步副作用

  • SideEffect

2. 协程异步任务

  • LaunchedEffect
  • produceState

3. 带清理 / 订阅

  • DisposableEffect

4. 保持最新值(解决旧值捕获)

  • rememberUpdatedState

5. State ↔ Flow 互转

  • snapshotFlow
  • collectAsStateWithLifecycle

二、逐个核心 API 速查(最强总结版)

1) SideEffect

一句话:每次重组后,同步执行一段非 UI 逻辑

触发:每次重组必跑

协程:❌ 不能 suspend

清理:❌ 无典型场景

  • 埋点、日志
  • 更新外部原生 View(AudioWaveView)
  • 避免直接在重组域写副作用

禁忌

  • 不要更新 State(会死循环)
  • 不要做耗时 / 异步

2) LaunchedEffect(key)

一句话:key 变化时,启动协程做异步任务

触发:key 变化 / 首次进入

协程:✅ 可 suspend

清理:自动取消协程

典型场景

  • 网络请求
  • 动画
  • 轮询、定时任务
  • 长循环(录音振幅更新)

技巧

  • LaunchedEffect(Unit):只执行一次
  • key 越多,控制越精细

3) DisposableEffect(key)

一句话:带onDispose的 Effect,必须成对 “注册 / 释放”

触发:key 变化 / 首次进入

协程:❌ 不能 suspend

清理:✅ onDispose{} 必须写

典型场景

  • 注册 / 反注册监听
  • 广播、传感器
  • 第三方 SDK 回调绑定
  • 播放器、录音器释放

4) rememberUpdatedState

一句话:包一个值,让长协程 / 回调永远读到最新版

触发:外部值自动同步

重组:❌ 不触发重组

解决问题:LaunchedEffect 里捕获旧值

典型场景

  • 长循环协程 + 外部参数变化
  • 注册的回调里要用最新参数
  • 录音振幅、播放进度等持续更新值

5) produceState

一句话:异步数据 → 自动生成 Compose State

返回State<T>

协程:✅ suspend

清理:✅ awaitDispose{}

典型场景

  • 网络请求转 UI 状态
  • 数据库监听
  • 录音振幅轮询转 State
  • 订阅 / 回调转 State

优势

不用自己写 mutableStateOf + LaunchedEffect


6) snapshotFlow

一句话:Compose State 变化 → 转换成 Kotlin Flow

能力:防抖、过滤、map、合并、延迟

典型场景

  • 搜索框防抖 debounce
  • 状态过滤 / 转换
  • 多 State 合并监听
  • 动画平滑、波形抖动抑制

核心

State 变 → Flow 自动发射新值

7) collectAsStateWithLifecycle

一句话:Flow → 转成生命周期安全的 Compose State

场景:ViewModel 暴露 Flow,UI 收集并显示

优势

  • 生命周期安全
  • 避免页面不可见时浪费资源

三、终极选择流程图(按这个选永远不错)

第一步:是同步还是异步?

  • **同步轻量操作(埋点 / 日志 / 更新外部对象)**→ SideEffect
  • 异步 / 协程 / 延迟 / 请求 / 循环→ 第二步

第二步:要不要返回 State 给 UI 用?

  • 要返回 State 直接显示→ produceState
  • 只做任务,不输出 State→ LaunchedEffect

第三步:是否需要注册 / 订阅 / 释放?

  • **必须手动清理(注册 / 反注册)**→ DisposableEffect

第四步:协程 / 回调里参数会过时吗?

  • 会,需要永远读最新值→ rememberUpdatedState

第五步:需要防抖 / 过滤 / 合并状态?

  • → snapshotFlow

四、6 大 API 最强对比表(面试直接背)

API触发时机协程清理核心用途
SideEffect每次重组后同步副作用
LaunchedEffectkey 变化自动取消异步任务
DisposableEffectkey 变化✅onDispose订阅 / 释放
rememberUpdatedState值自动同步保持值最新
produceStatekey 变化✅awaitDispose异步→State
snapshotFlowState 变化✅配合协程自动取消State 转 Flow 防抖

五、和你业务最相关的组合示例(录音波形)

@Composable
fun WaveView(recorder: AudioRecorder) {
    // 1. 轮询振幅 → 转 State
    val amplitude by produceState(0f, recorder) {
        while (recorder.isRecording) {
            delay(300)
            val amp = recorder.currentRecordMaxAmplitude / 32767f
            value = amp.coerceIn(0f, 1f)
        }
    }

    // 2. 保证拿到最新值
    val currentAmp by rememberUpdatedState(amplitude)

            // 3. State 转 Flow → 防抖
            LaunchedEffect(Unit) {
        snapshotFlow { currentAmp }
            .debounce(100)
                .collect {
            // 4. 同步更新外部 View
            SideEffect {
                audioWaveView.setAmplitude(it)
            }
        }
    }
}

六、一句话终极口诀

重组同步用 Side,

异步任务用 Launch,

订阅释放用 Disposable,

参数过时用 Updated,

异步转状态用 Produce,

防抖过滤用 Flow。