先用人话理解
协程是 Kotlin 中组织异步任务的方式。suspend 表示函数可以挂起等待;launch 启动不直接返回结果的任务,async 启动并通过 await 获取结果。Android 中不要在主线程执行阻塞式网络请求。
本课要点:Dispatchers.IO 适合阻塞式 I/O 工作;Dispatchers.Main 用于界面交互。lifecycleScope 会随生命周期结束而取消相关协程。
代码例子
先读注释,再关注每一行如何把数据变成结果。
KOTLIN/JVM · 需要协程依赖
// 需要 kotlinx-coroutines-core 依赖;可在普通 Kotlin/JVM Gradle 项目中运行
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
suspend fun loadProfile(): String {
delay(300) // 模拟等待,不会阻塞协程所在的线程
return "用户资料"
}
suspend fun loadOrders(): String {
delay(300)
return "订单列表"
}
fun main() = runBlocking {
val (profile, orders) = coroutineScope {
val profileTask = async { loadProfile() }
val ordersTask = async { loadOrders() }
profileTask.await() to ordersTask.await() // 两个任务并发启动
}
println(profile)
println(orders)
}再看一个用法
ANDROID · lifecycleScope
// Android 示例:需要 kotlinx-coroutines-android,以及 Activity/Fragment 的 lifecycleScope
lifecycleScope.launch {
val (profile, orders) = coroutineScope {
val profileTask = async(Dispatchers.IO) { repository.loadProfile() }
val ordersTask = async(Dispatchers.IO) { repository.loadOrders() }
profileTask.await() to ordersTask.await()
}
render(profile, orders) // launch 默认回到 Main,可在这里更新界面
}动手改一改
把 loadOrders() 的返回文本改成“收藏列表”,再运行 main(),确认两个任务都能返回结果。
运行要求:这是 Kotlin/JVM + kotlinx-coroutines 示例,不是 Android 模拟器项目。普通 JVM 项目的 dependencies 中添加 implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0");Android 项目使用 implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0"),并按项目的 Kotlin 版本核对兼容性。
查看协程官方文档 ↗三道小测
先自己选择,再展开答案。答错也没关系,重要的是知道为什么。
1. suspend 表示什么?
查看答案与解析
正确答案:B。抓住题目中的核心概念,重新对照示例理解。
2. async 的结果通常如何取得?
查看答案与解析
正确答案:A。回到概念和代码示例,再解释一次为什么。
3. Android 网络 I/O 通常适合哪个调度器?
查看答案与解析
正确答案:B。抓住题目中的核心概念,重新对照示例理解。
深入阅读
想继续往下挖,可以阅读 Kotlin / Android 官方文档。
打开官方文档 ↗标记学习进度
进度保存在当前浏览器的 localStorage 中。