Kotlin 协程
2026/8/23大约 2 分钟
Kotlin 协程从入门到进阶
协程(Coroutine)是 Kotlin 提供的轻量级并发解决方案,用于简化异步编程,避免回调地狱。
一、协程基础概念
协程:可挂起(suspend)和恢复的计算单元,运行在线程之上,但不受线程调度限制。
import kotlinx.coroutines.*
fun main() = runBlocking {
launch { // 启动一个协程
delay(1000L) // 挂起 1 秒(不阻塞线程)
println("World")
}
println("Hello")
}
// 输出:Hello → World二、协程构建器
| 构建器 | 作用 |
|---|---|
launch | 启动协程,返回 Job,不返回结果 |
async | 启动协程,返回 Deferred<T>,可获取结果 |
runBlocking | 阻塞当前线程直到完成(仅测试/主函数使用) |
三、调度器(Dispatcher)
| 调度器 | 线程 | 适用场景 |
|---|---|---|
Dispatchers.Main | 主线程 | UI 操作 |
Dispatchers.IO | IO 线程池 | 网络、磁盘 |
Dispatchers.Default | CPU 密集型 | 计算任务 |
Dispatchers.Unconfined | 不限制 | 极少使用 |
viewModelScope.launch(Dispatchers.IO) {
val data = repository.fetchData() // IO 线程执行
withContext(Dispatchers.Main) {
_uiState.value = data // 主线程更新 UI
}
}四、结构化并发
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
// Job:取消与等待
val job = scope.launch { ... }
job.cancel()
job.join()
// 子协程:父协程取消时自动取消子协程
scope.launch {
launch { work1() }
launch { work2() }
}异常处理:SupervisorJob 使子协程异常互不影响,配合 CoroutineExceptionHandler 统一兜底。
五、Flow 冷流
fun fetchData(): Flow<String> = flow {
emit("第一次数据")
delay(1000)
emit("第二次数据")
}
// 收集
scope.launch {
fetchData()
.flowOn(Dispatchers.IO) // 切换上游执行线程
.map { it.uppercase() } // 操作符
.catch { e -> emit("error: $e") } // 异常捕获
.collect { data -> println(data) }
}六、实战建议
- 页面级作用域:使用
viewModelScope与lifecycleScope,避免内存泄漏 - 避免全局 scope:不要用
GlobalScope(无法取消,易泄漏) - 线程切换:用
withContext而非多次launch - 背压:高频数据流使用
conflate或collectLatest
📖 进阶阅读:协程 Flow 与 RxJava | 线程池与并发