一、produceState 到底是什么?
一句话定义
produceState 是一个 Compose 内置的 Effect,用于在协程中异步生产数据,并自动将其转换为 State<T>,让 UI 可以直接观察使用。
它帮你做了三件事:
- 创建并管理一个
State对象 - 提供一个协程作用域执行异步代码
- 自动绑定生命周期(退出组合自动取消协程,不会泄漏)
二、核心语法结构
kotlin
kotlin
@Composable
fun <T> produceState(
initialValue: T, // 【必须】初始值
key1: Any?, // 【可选】key,变化会重启协程
... // 最多支持 3 个 key
block: suspend ProduceStateScope<T>.() -> Unit
): State<T>
内部核心:
initialValue:第一次重组时返回的值key:key 变化 → 取消旧协程 → 启动新协程value:特殊变量,赋值即可更新 State,触发 UI 重组awaitDispose {}:清理资源(如反注册、关闭流)
三、最基础标准使用示例
kotlin
kotlin
@Composable
fun UserInfoScreen(userId: String) {
// 1. 定义:自动返回 State<User>
val userState: State<User?> = produceState(
initialValue = null, // 初始状态
key1 = userId // userId 变化,重新获取数据
) {
// 2. 协程作用域
val user = api.getUserById(userId) // 网络请求
value = user // 3. 赋值 -> 更新 State -> UI 刷新
}
// UI 直接使用
Text(text = userState.value?.name ?: "加载中...")
}
四、produceState 核心特点(必背)
-
返回
State<T>,可直接用于重组 -
内部是协程,支持 suspend 函数
-
自动管理生命周期
- 进入组合:启动协程
- 退出组合:取消协程
- Key 变化:重启协程
-
无需手动创建
mutableStateOf -
自带资源清理:
awaitDispose -
只能在 @Composable 函数中调用
五、最常用 4 大实战场景
场景 1:网络请求(一次性)
kotlin
kotlin
@Composable
fun LoadData() {
val dataState by produceState<Result<Data>>(Result.Loading, key1 = id) {
value = try { Result.Success(api.fetch(id)) }
catch (e: Exception) { Result.Error(e) }
}
when (dataState) {
is Result.Loading -> Loading()
is Result.Success -> ShowData(dataState.data)
is Result.Error -> ErrorView()
}
}
场景 2:轮询 / 定时任务(你的录音振幅)
kotlin
kotlin
@Composable
fun rememberAmplitudeState(recorder: AudioRecorder): State<Float> {
return produceState(initialValue = 0f, key1 = recorder) {
// 持续轮询
while (recorder.isRecording) {
delay(300) // 300ms 刷新
val amp = recorder.currentRecordMaxAmplitude / 32767f
value = amp.coerceIn(0f, 1f) // 更新振幅
}
}
}
场景 3:回调 / 订阅 / 监听 → 转 State
kotlin
kotlin
@Composable
fun rememberLocationState(): State<Location> {
return produceState(initialValue = Location.Default) {
val callback = LocationCallback { location ->
value = location // 监听 -> 自动更新 State
}
locationManager.register(callback)
// 关键:清理
awaitDispose {
locationManager.unregister(callback)
}
}
}
场景 4:数据流(Flow)→ 转 State
kotlin
kotlin
@Composable
fun observeDataFlow(): State<Data> {
return produceState(initialValue = emptyData()) {
dataFlow.collect { data ->
value = data
}
}
}
六、重要 API:awaitDispose ()
作用:协程取消 /key 变化 / 组件销毁时,执行清理
kotlin
scss
produceState(Unit) {
val callback = MyListener { value = it }
register(callback)
// 必须释放的资源
awaitDispose {
unregister(callback)
}
}
七、produceState 与 LaunchedEffect 区别(面试必考)
表格
| 特性 | produceState | LaunchedEffect |
|---|---|---|
| 返回值 | 返回 State<T> |
无返回值 |
| 作用 | 异步数据 → UI 状态 | 执行异步任务 |
| 状态管理 | 自动创建、自动更新 | 需手动维护 State |
| 代码量 | 极少 | 较多 |
| 适用场景 | UI 展示的数据来源 | 事件、动画、无状态任务 |
总结
- 要数据给 UI 用 →
produceState - 只执行任务,不要返回值 →
LaunchedEffect
八、与其他 Effect 的关系
- LaunchedEffect:做任务
- produceState :做任务 + 输出 State
- SideEffect:同步副作用
- DisposableEffect:注册 / 清理
- rememberUpdatedState:保持值最新
九、使用注意事项(避坑)
- 必须提供
initialValue - key 正确设置,避免不必要重启
- 循环必须配合条件,避免无限运行
- 敏感资源必须用
awaitDispose释放 - 不要在内部更新外部 State(会导致混乱)
十、最终极简总结
produceState = 协程 + State + 生命周期管理
- 把异步数据 变成Compose 可观察状态
- 自动管理协程,安全不泄漏
- 适合:网络、轮询、监听、订阅、数据流