Kotlin 协程与 Flow
适用于 Android 和 Kotlin 多平台项目的结构化并发模式、基于 Flow 的响应式流以及协程测试。
何时启用
- 使用 Kotlin 协程编写异步代码
- 使用 Flow、StateFlow 或 SharedFlow 实现响应式数据
- 处理并发操作(并行加载、防抖、重试)
- 测试协程和 Flow
- 管理协程作用域与取消
结构化并发
作用域层级
始终使用结构化并发——绝不使用 GlobalScope:
并行分解
使用 coroutineScope + async 处理并行工作:
SupervisorScope
当子协程失败不应取消同级协程时,使用 supervisorScope:
Flow 模式
Cold Flow —— 一次性操作到流的转换
用于 UI 状态的 StateFlow
WhileSubscribed(5_000) 会在最后一个订阅者离开后,保持上游活动 5 秒——可在配置更改时存活而无需重启。
组合多个 Flow
Flow 操作符
用于一次性事件的 SharedFlow
调度器
在 KMP 中,使用 Dispatchers.Default 和 Dispatchers.Main(在所有平台上可用)。Dispatchers.IO 仅适用于 JVM/Android——在其他平台上使用 Dispatchers.Default 或通过依赖注入提供。
取消
协作式取消
长时间运行的循环必须检查取消状态:
使用 try/finally 进行清理
测试
使用 Turbine 测试 StateFlow
使用 TestDispatcher 测试
模拟 Flow
应避免的反模式
- 使用
GlobalScope——会导致协程泄漏,且无法结构化取消 - 在没有作用域的情况下于
init {}中收集 Flow——应使用viewModelScope.launch - 将
MutableStateFlow与可变集合一起使用——始终使用不可变副本:_state.update { it.copy(list = it.list + newItem) } - 捕获
CancellationException——应让其传播以实现正确的取消 - 使用
flowOn(Dispatchers.Main)进行收集——收集调度器是调用方的调度器 - 在
@Composable中创建Flow而不使用remember——每次重组都会重新创建 Flow
参考
关于 Flow 在 UI 层的消费,请参阅技能:compose-multiplatform-patterns。
关于协程在各层中的适用位置,请参阅技能:android-clean-architecture。


