1.1 协程使用场景矩阵
1.1.1 异步任务处理(网络请求示例)
kotlin
// 传统回调方式 vs 协程方式对比
class UserRepository {
// 回调地狱示例
fun fetchUserData(callback: (User) -> Unit) {
apiService.getUserProfile { profile ->
apiService.getUserFriends(profile.id) { friends ->
apiService.getUserPosts(profile.id) { posts ->
callback(User(profile, friends, posts))
}
}
}
}
// 协程优雅实现
suspend fun fetchUserDataCoroutine(): User {
val profile = apiService.getUserProfile() // 挂起函数
val friends = async { apiService.getUserFriends(profile.id) }
val posts = async { apiService.getUserPosts(profile.id) }
return User(profile, friends.await(), posts.await())
}
}
// ViewModel中使用
class UserViewModel : ViewModel() {
private val repo = UserRepository()
val userData = MutableStateFlow<User?>(null)
fun loadData() {
viewModelScope.launch {
try {
val data = repo.fetchUserDataCoroutine()
userData.value = data
} catch (e: Exception) {
// 统一异常处理
}
}
}
}
场景优势分析:
- 消除回调地狱,代码线性化
- 统一异常处理
- 自动取消机制(当ViewModel清除时自动取消)
1.1.2 事件流处理(UI事件防抖)
kotlin
// 搜索框输入防抖实现
class SearchViewModel : ViewModel() {
private val _searchQuery = MutableSharedFlow<String>()
val searchResults = MutableStateFlow<List<Result>>(emptyList())
init {
viewModelScope.launch {
_searchQuery
.debounce(300) // 300ms防抖
.distinctUntilChanged() // 值相同时跳过
.filter { it.length > 2 } // 最小长度限制
.flatMapLatest { query ->
// 取消前一个搜索请求
repository.search(query)
}
.collect { results ->
searchResults.value = results
}
}
}
fun onSearchQueryChanged(query: String) {
viewModelScope.launch {
_searchQuery.emit(query)
}
}
}
1.1.3 复杂状态管理(多步骤订单流程)
kotlin
class OrderProcessor {
suspend fun processOrder(order: Order): OrderResult {
return supervisorScope {
// 步骤1: 验证库存(并行执行)
val stockValidation = async { validateStock(order.items) }
// 步骤2: 用户身份验证
val userAuth = async { authenticateUser(order.userId) }
// 等待前置任务完成
val (stockResult, authResult) = awaitAll(stockValidation, userAuth)
if (!stockResult.success) throw StockException(stockResult.message)
if (!authResult.success) throw AuthException(authResult.message)
// 步骤3: 支付处理
val paymentResult = processPayment(order.payment)
// 步骤4: 创建订单记录
val orderRecord = createOrderRecord(order, paymentResult)
// 步骤5: 发送通知
launch { sendNotification(order.userId, orderRecord.id) }
return@supervisorScope OrderResult.Success(orderRecord)
}
}
}
1.2 挂起函数底层机制
1.2.1 CPS转换原理(Continuation Passing Style)
Kotlin源码:
kotlin
suspend fun fetchUserData(): User {
val profile = fetchProfile()
val friends = fetchFriends()
return User(profile, friends)
}
反编译的Java等价代码(简化):
ini
public final Object fetchUserData(Continuation $completion) {
// 创建状态机
FetchUserDataStateMachine stateMachine = new FetchUserDataStateMachine($completion);
switch(stateMachine.label) {
case 0:
// 初始状态
stateMachine.label = 1;
Object result = fetchProfile(stateMachine);
if (result == COROUTINE_SUSPENDED)
return COROUTINE_SUSPENDED;
// 隐式fall-through
case 1:
// 恢复点1:profile已获取
Profile profile = (Profile)stateMachine.result;
stateMachine.profile = profile;
stateMachine.label = 2;
result = fetchFriends(stateMachine);
if (result == COROUTINE_SUSPENDED)
return COROUTINE_SUSPENDED;
// 隐式fall-through
case 2:
// 恢复点2:friends已获取
Friends friends = (Friends)stateMachine.result;
User user = new User(stateMachine.profile, friends);
return user;
}
}
关键机制:
- 状态机转换:每个挂起点对应一个状态(label)
- 挂起标志 :当函数返回
COROUTINE_SUSPENDED
时,协程挂起 - 隐式fall-through:非挂起情况直接执行下一状态
- 续体传递:Continuation保存恢复执行所需上下文
1.2.2 挂起函数执行流程

1.3 协程上下文实现树
1.3.1 上下文组成元素
scss
// 创建包含多个元素的上下文
val customContext = Job() + Dispatchers.IO + CoroutineName("network-request")
// 等价于
val customContext = CoroutineContextImpl(
JobElement(job),
DispatcherElement(Dispatchers.IO),
NameElement("network-request")
)
1.3.2 上下文继承与覆盖
源码解析(CoroutineContext.kt):
kotlin
public operator fun plus(context: CoroutineContext): CoroutineContext {
// 空上下文处理
if (context === EmptyCoroutineContext) return this
// 合并逻辑
return context.fold(this) { acc, element ->
val removed = acc.minusKey(element.key)
if (removed === EmptyCoroutineContext) {
element
} else {
// 创建组合上下文
val interceptor = removed[ContinuationInterceptor]
if (interceptor == null) {
CombinedContext(removed, element)
} else {
val left = removed.minusKey(ContinuationInterceptor)
if (left === EmptyCoroutineContext) {
CombinedContext(element, interceptor)
} else {
CombinedContext(CombinedContext(left, element), interceptor)
}
}
}
}
}
关键点:
- 上下文通过
plus
操作符合并 - 拦截器(如Dispatcher)总是保持在最后位置
- 相同Key的元素会被覆盖
1.3.3 拦截器工作流程
kotlin
// 拦截器核心实现
internal abstract class ContinuationInterceptorImpl : ContinuationInterceptor {
override fun <T> interceptContinuation(
continuation: Continuation<T>
): Continuation<T> {
// 创建可拦截的续体
return DispatchedContinuation(this, continuation)
}
}
// DispatchedContinuation.resumeWith()
override fun resumeWith(result: Result<T>) {
// ...
dispatcher.dispatch(context, Runnable {
continuation.resume(result)
})
}
拦截过程:
- 协程创建时,续体被包装为
DispatchedContinuation
- 恢复执行时,调用
dispatch
方法切换到目标线程 - 在目标线程执行实际的
resume
操作
1.4 调度器内核实现
1.4.1 Android调度器体系

1.4.2 Dispatchers.IO 工作窃取算法
核心源码(Dispatched.kt):
kotlin
internal class LimitingDispatcher(
private val dispatcher: ExecutorCoroutineDispatcher,
private val parallelism: Int
) : ExecutorCoroutineDispatcher() {
private val queue = ConcurrentLinkedQueue<Runnable>()
private val inFlightTasks = atomic(0)
override fun dispatch(context: CoroutineContext, block: Runnable) {
// 添加到队列并尝试调度
queue.add(block)
tryDispatch()
}
private fun tryDispatch() {
while (inFlightTasks.value < parallelism) {
val task = queue.poll() ?: return
inFlightTasks.incrementAndGet()
dispatcher.dispatch(this, Runnable {
try {
task.run()
} finally {
inFlightTasks.decrementAndGet()
tryDispatch() // 任务完成后尝试调度下一个
}
})
}
}
}
工作流程:
- 任务进入并发队列
- 检查当前运行任务数是否小于并行度限制
- 从队列取出任务,提交给底层执行器
- 任务完成后,减少计数器并再次尝试调度
1.4.3 主线程调度优化
Android特有优化(HandlerDispatcher.kt):
kotlin
internal class HandlerContext private constructor(
private val handler: Handler,
private val name: String?
) : HandlerDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
// 使用异步消息避免VSYNC同步屏障
handler.post(block)
// 特殊优化:Choreographer同步
if (Looper.myLooper() == handler.looper &&
context[ChoreographerFrameCallback] != null) {
postFrameCallback(context)
}
}
private fun postFrameCallback(context: CoroutineContext) {
val callback = context[ChoreographerFrameCallback]!!
Choreographer.getInstance().postFrameCallback(callback)
}
}
优化点:
- 异步消息:避免被同步屏障阻塞
- 帧回调集成:与Choreographer协作优化UI更新
- Looper检测:已在主线程时直接执行
本章小结
本章深入探讨了协程的核心机制:
- 使用场景:从异步任务到复杂状态管理
- 挂起原理:CPS转换与状态机实现
- 上下文系统:树形结构与拦截机制
- 调度器内核:工作窃取算法与Android优化
在下一章,我们将深入探讨结构化并发模型,解析Job树形结构和Android生命周期集成机制。