Kotlin协程机制
目录
✅ 一、什么是协程(Coroutine)?
🧠 为什么需要协程?
✅ 二、Kotlin 原生支持协程的关键在哪?
✅ 三、协程的核心概念
✅ 四、基础示例:Hello 协程!
✅ 五、Kotlin 原生协程的关键组成
1️⃣ suspend 函数:挂起函数
2️⃣ 启动协程:launch vs async
✅ launch:启动协程,不返回值(用于 fire-and-forget)
3️⃣ CoroutineScope:生命周期管理
4️⃣ 调度器(Dispatcher)控制线程
✅ 六、协程的原生挂起与恢复机制(底层原理简化)
✅ 七、协程与结构化并发
✅ 八、协程在实际项目中的应用(Android 举例)
✅ 九、协程常用库
✅ 十、总结:Kotlin 原生协程的优势
Kotlin 的协程(Coroutines)是它最强大的特性之一,尤其在处理 异步任务、并发编程 时,表现非常出色。它被称为是 Kotlin 的“原生协程支持”,这是因为它是语言层面设计的,而不是依赖于第三方库或框架。
✅ 一、什么是协程(Coroutine)?
协程是一种 轻量级线程,它可以 挂起(暂停)和恢复,从而使异步代码看起来像同步代码,极大地提升代码的可读性和结构清晰度。
📌 类比:传统的线程是“重型卡车”,协程是“轻便摩托车”——更轻、更灵活。
🧠 为什么需要协程?
在 Android 或后端开发中,我们经常遇到以下问题:
-
耗时操作(如网络请求、数据库读写)不能在主线程执行。
-
Java 的回调写法非常臃肿(Callback Hell):
api.fetchData(new Callback() {
@Override
public void onResponse(...) {
// 嵌套回调
}
});
而协程让你写出像同步代码一样的异步逻辑👇:
val user = api.fetchUser() // 自动挂起等待结果
val posts = api.fetchPosts(user.id)
✅ 二、Kotlin 原生支持协程的关键在哪?
Kotlin 的协程并不是线程,而是基于一种叫做 挂起函数(suspend function) 的机制,加上一套调度器和协程构建器,构成了完整的原生协程模型。
✅ 三、协程的核心概念
概念 | 说明 |
---|---|
suspend | 表示一个 挂起函数,可以暂停和恢复执行 |
CoroutineScope | 协程的作用域,管理其生命周期 |
launch | 启动一个新的协程(不返回结果) |
async | 启动一个协程并返回一个 Deferred (可获取结果) |
delay() | 非阻塞式延时,挂起当前协程而不阻塞线程 |
Dispatcher | 协程的调度器,控制在哪个线程执行 |
✅ 四、基础示例:Hello 协程!
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(1000L)
println("Hello from coroutine!")
}
println("Hello from main!")
}
💡 输出顺序:
Hello from main!
Hello from coroutine!
📌 解析:
-
runBlocking {}
:创建一个主线程的协程环境。 -
launch {}
:启动一个协程,它在后台运行。 -
delay(1000L)
:挂起当前协程 1 秒,不阻塞主线程。
✅ 五、Kotlin 原生协程的关键组成
1️⃣ suspend
函数:挂起函数
suspend fun fetchUser(): User {
delay(1000) // 模拟网络请求
return User("Alice")
}
挂起函数只能在协程或其他挂起函数中调用,不会阻塞线程。
2️⃣ 启动协程:launch
vs async
✅ launch
:启动协程,不返回值(用于 fire-and-forget)
GlobalScope.launch {
println("I'm running in coroutine!")
}
✅ async
:启动协程,返回 Deferred
,用于获取结果
val result = GlobalScope.async {
doSomething()
}
println(result.await()) // 等待并获取结果
3️⃣ CoroutineScope
:生命周期管理
协程应该在 CoroutineScope
中启动,常见的作用域有:
-
GlobalScope
:全局作用域,不推荐长期使用 -
runBlocking
:用于测试或main()
函数 -
lifecycleScope
:在 Android 中绑定 Activity / Fragment 生命周期 -
viewModelScope
:在 Android ViewModel 中使用
4️⃣ 调度器(Dispatcher)控制线程
Dispatcher | 说明 |
---|---|
Dispatchers.Main | Android 主线程 |
Dispatchers.IO | 用于磁盘或网络操作 |
Dispatchers.Default | 用于 CPU 密集型操作 |
Dispatchers.Unconfined | 不限制线程,常用于测试 |
launch(Dispatchers.IO) {
// 执行网络请求
}
✅ 六、协程的原生挂起与恢复机制(底层原理简化)
Kotlin 协程的底层基于 状态机转换 + Continuation:
-
Kotlin 编译器会把
suspend
函数编译成 状态机。 -
每次调用
suspend
函数时,会自动保存当前的执行状态。 -
等待挂起的任务完成后,再恢复到原来的状态继续执行。
🔧 这一切你都不需要手动写,Kotlin 帮你自动完成!
✅ 七、协程与结构化并发
结构化并发是一种有生命周期的协程管理方式,它确保:
-
所有子协程都会在父协程取消时被取消。
-
协程不会泄漏。
fun main() = runBlocking {
coroutineScope {
launch {
delay(1000)
println("Task 1 done")
}
launch {
delay(500)
println("Task 2 done")
}
}
println("All tasks completed")
}
✅ 八、协程在实际项目中的应用(Android 举例)
viewModelScope.launch {
try {
val user = userRepository.getUser() // suspend 函数
_uiState.value = UiState.Success(user)
} catch (e: Exception) {
_uiState.value = UiState.Error("网络错误")
}
}
-
非阻塞网络请求
-
自动取消协程,防止内存泄漏
-
结合 LiveData、StateFlow 使用
✅ 九、协程常用库
库 | 用途 |
---|---|
kotlinx.coroutines | Kotlin 官方协程库 |
ktor | Kotlin 原生 Web 框架,全面基于协程 |
Retrofit + Coroutine CallAdapter | 支持挂起函数调用网络接口 |
✅ 十、总结:Kotlin 原生协程的优势
优势 | 说明 |
---|---|
✅ 语法简洁 | 让异步代码看起来像同步 |
✅ 非阻塞 | 不阻塞线程,提高性能 |
✅ 生命周期安全 | 可与 Android 生命周期绑定 |
✅ 性能优越 | 比线程更轻量、资源占用少 |
✅ 原生支持 | 不依赖第三方库,语言级支持xie che |