produceState的使用:

一、produceState 到底是什么?

一句话定义

produceState 是一个 Compose 内置的 Effect,用于在协程中异步生产数据,并自动将其转换为 State<T>,让 UI 可以直接观察使用。

它帮你做了三件事:

  1. 创建并管理一个 State 对象
  2. 提供一个协程作用域执行异步代码
  3. 自动绑定生命周期(退出组合自动取消协程,不会泄漏)

二、核心语法结构

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 核心特点(必背)

  1. 返回 State<T> ,可直接用于重组

  2. 内部是协程,支持 suspend 函数

  3. 自动管理生命周期

    • 进入组合:启动协程
    • 退出组合:取消协程
    • Key 变化:重启协程
  4. 无需手动创建 mutableStateOf

  5. 自带资源清理:awaitDispose

  6. 只能在 @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:保持值最新

九、使用注意事项(避坑)

  1. 必须提供 initialValue
  2. key 正确设置,避免不必要重启
  3. 循环必须配合条件,避免无限运行
  4. 敏感资源必须用 awaitDispose 释放
  5. 不要在内部更新外部 State(会导致混乱)

十、最终极简总结

produceState = 协程 + State + 生命周期管理

  • 异步数据 变成Compose 可观察状态
  • 自动管理协程,安全不泄漏
  • 适合:网络、轮询、监听、订阅、数据流
相关推荐
阿巴斯甜2 小时前
snapshotFlow的使用
android jetpack
菜鸟国国3 小时前
从0开始学Jetpack Compose|第二篇:基础组件+核心布局,从零搭建实用UI
android jetpack
simplepeng3 小时前
mutableStateOf(list) vs mutableStateListOf():该如何选择?
android jetpack
zh_xuan20 小时前
Android Jetpack DataStore存储数据
android·android jetpack·datastore
simplepeng1 天前
MVI with Jetpack Compose:让你的应用更简洁和整洁
android jetpack
simplepeng1 天前
别再让团队困惑:少有人提及的 MVI 命名规范
android jetpack
zh_xuan1 天前
Android Jetpack 使用Room数据库
android·android jetpack·room
alexhilton4 天前
Jetpack Compose中的富文本输入
android·kotlin·android jetpack
海盐芝士不加糖4 天前
我又又又辞职了,然后做了一款“离线版微信”
kotlin·app·android jetpack