
LifecycleScope 绑定Activity / Fragment页面销毁 → 协程自动取消防止内存泄漏ViewModelScope 绑定ViewModelViewModel 销毁 → 自动取消页面旋转还在销毁才没CoroutineScope 通用、原始的 Scope需要自己管理生命周期不手动 cancel 会内存泄漏最后要更新 UI → 用 Main suspend全程后台、不碰 UI、只处理数据 → 用 IO suspendlaunch(Dispatchers.Main) {// 这里主线程val data dao.getUser()// 回来主线程tv.text data.name // ✅ 能直接更新 UI卡主线程}launch(Dispatchers.IO) {// 这里IO 子线程val data dao.getUser()// 回来还是 IO 子线程tv.text data.name // ❌ 崩溃子线程不能更新 UI不卡主线程}如果没有操作UI效果是一样的launch(Dispatchers.IO) {val job1 launch { A() }val job2 launch { B() }val job3 launch { C() }joinAll(job1, job2, job3)}并发可能并行launch(Dispatchers.Main) {val job1 launch { A() }val job2 launch { B() }val job3 launch { C() }joinAll(job1, job2, job3)}并发但不是并行主线程上轮流执行、交替执行源码解析launch → dispatch → run → resume → resumeImpl → invokeSuspend① CoroutineScope.launch { ... }构建协程启动参数上下文、调度器、启动模式创建协程任务对象AbstractCoroutineJob 和 Continuation 的载体↓② AbstractCoroutine.start()AbstractCoroutine Job ContinuationJob 是啥Job 就是协程的句柄 / 任务对象它只负责三件事协程当前状态New → Active → Completing → Completed / Cancelled父子协程的结构化关系父 Job 管理子 Job父取消 → 子全部取消父等子执行完手动控制协程job.cancel()job.join()job.isActive / isCompleted / isCancelled它不保存执行位置、不保存局部变量、不负责 resume。Continuation有啥label执行到第几行挂起了一开始 label 0result局部变量、临时值、参数completion外层 continuation恢复后继续往上传递结果如果协程套协程子协程的completion父协程的continuation父协程的completion上层 completion框架层context协程上下文↓③ DispatchedContinuation.resume(Unit)入口方法触发协程开始执行或异步回调后恢复执行挂起 保存当前执行状态 → 退出当前函数 → 释放线程 → 等待回调 →恢复时从断点继续↓④ DispatchedContinuation.resumeWith(Result.success(Unit))判断是否需要立即调度dispatch还是直接在当前线程执行未调度 调度器不为空 → 进入 dispatch 流程↓⑤ CoroutineDispatcher.dispatch(...) 调度线程这里是真正切线程/线程的地方如果是 Dispatchers.Main → 内部调用 Handler.post(continuationRunnable)如果是 Dispatchers.IO / Default → 内部交给 ThreadPoolExecutor 提交任务↓⑥ DispatchedContinuation.run() 在线程上执行在线程池分配的线程上被执行真正开始执行协程体代码↓⑦ ContinuationImpl.resume(result)调用栈进入 Kotlin 编译器生成的状态机基类处理异常、结果包装↓⑧ BaseContinuationImpl.resumeImpl(result)协程状态机核心执行方法根据当前 label 跳转到对应挂起点恢复执行internal abstract class BaseContinuationImpl( private val completion: Continuation?) : Continuation {public operator fun invokeSuspend(result: Any?): Any?public final override fun resumeWith(result: Any?) {val outcome invokeSuspend(result)if (outcome COROUTINE_SUSPENDED) {return // 直接 return 协程挂起了挂起 保存当前执行状态 →退出当前函数 → 释放线程 → 等待回调→ 恢复时从断点继续}// 如果没有挂起就继续执行完成completion.resumeWith(...)}}↓⑨ BaseContinuationImpl.invokeSuspend(result)final class MySuspendFunc$1 extends SuspendLambda {int label; // 状态Object result; // 结果/异常// 局部变量缓存...OverrideObject invokeSuspend(Object $result) {this.result $result;switch (label) {case 0: // 初始状态// 执行第一段代码label 1;//保存当前执行状态 把 Continuation 内存对象的引用赋值给了另一个对象 异步任务本身 / 回调对象 / 系统任务对象挂起 保存当前执行状态→ 退出当前函数 → 释放线程 → 等待回调 → 恢复时从断点继续return COROUTINE_SUSPENDED; // 挂起case 1: // 恢复后状态// 从挂起点继续执行return 最终结果;default:throw new IllegalStateException();}}}