第 5 课2026.07.21
网络请求、数据库读取等操作不会立即完成。KMP 可以在共享代码中用协程统一描述这些异步任务,让 Android 和 iOS 复用同一套业务流程。
第 5 课:KMP 共享协程基础
- 日期:2026-07-21
- 课程序号:05
- 知识点:在
commonMain中用suspend表达异步任务
用途
网络请求、数据库读取等操作不会立即完成。KMP 可以在共享代码中用协程统一描述这些异步任务,让 Android 和 iOS 复用同一套业务流程。
核心概念
suspend函数可以挂起并稍后恢复,不等于阻塞当前线程。suspend函数只能由另一个suspend函数或协程调用。- 共享业务层负责提供异步 API;调用方负责决定协程何时启动、何时取消。
- 不要在共享仓库内部创建与页面生命周期脱节的全局协程。
示例代码
先在共享模块的 commonMain 中加入协程核心依赖。版本号应统一使用项目已有的版本目录或版本变量:
kotlin
kotlin {
sourceSets {
commonMain.dependencies {
implementation(libs.kotlinx.coroutines.core)
}
}
}commonMain/UserRepository.kt:
kotlin
import kotlinx.coroutines.delay
data class User(
val id: Long,
val name: String,
)
class UserRepository {
suspend fun loadUser(): User {
delay(300) // 模拟网络或数据库等待
return User(id = 1L, name = "KMP Learner")
}
}Android 页面可以用自己的生命周期作用域调用:
kotlin
lifecycleScope.launch {
val user = UserRepository().loadUser()
println(user.name)
}关键边界是:UserRepository 只暴露 suspend API,不持有页面的 CoroutineScope;页面销毁时,lifecycleScope 会负责取消任务。
5 分钟练习
给 UserRepository 增加一个 suspend fun loadGreeting(): String:等待 100 毫秒后返回 "Hello, KMP!"。
参考答案
kotlin
import kotlinx.coroutines.delay
class UserRepository {
suspend fun loadGreeting(): String {
delay(100)
return "Hello, KMP!"
}
}调用它时仍应由外部已有的协程作用域启动任务,而不是在 loadGreeting() 内创建新的全局作用域。
与上一课的联系
上一课学习了用 commonTest 验证共享逻辑。本课开始引入异步共享逻辑;后续可以使用 runTest 测试 suspend 函数,并继续学习用 Flow 表达持续变化的数据流。