2.1 作用域使用场景与最佳实践
2.1.1 Android作用域体系全景
作用域选择指南:
- Activity/Fragment :
lifecycleScope
(自动取消) - ViewModel :
viewModelScope
(安全访问UI状态) - 全局后台任务 :自定义作用域(非
GlobalScope
) - 跨组件任务 :
Application
作用域(谨慎使用)
2.1.2 ViewModel作用域源码解析
kotlin
// ViewModel.kt 扩展属性
val ViewModel.viewModelScope: CoroutineScope
get() {
val scope: CoroutineScope? = this.getTag(JOB_KEY)
if (scope != null) {
return scope
}
return setTagIfAbsent(
JOB_KEY,
CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
)
}
// 关闭逻辑
internal class CloseableCoroutineScope(
context: CoroutineContext
) : Closeable, CoroutineScope {
override val coroutineContext: CoroutineContext = context
override fun close() {
coroutineContext.cancel()
}
}
// ViewModel清除时触发
override fun onCleared() {
super.onCleared()
(viewModelScope as CloseableCoroutineScope).close()
}
关键设计:
- 延迟初始化:首次访问时创建作用域
- SupervisorJob:子协程异常不会影响父级
- Main.immediate:立即执行主线程任务
- 自动取消:ViewModel销毁时清理所有协程
2.1.3 自定义作用域实现
kotlin
class AppCoroutineScope : CoroutineScope {
// 使用SupervisorJob防止单点失败
private val job = SupervisorJob()
// 自定义线程池
private val dispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
override val coroutineContext: CoroutineContext
get() = job + dispatcher + CoroutineName("app-scope") + CoroutineExceptionHandler { _, e ->
logError("Scope error", e)
}
fun release() {
job.cancel("App scope released")
(dispatcher.executor as? ExecutorService)?.shutdown()
}
}
// Application中使用
class MyApp : Application() {
val appScope = AppCoroutineScope()
override fun onTerminate() {
super.onTerminate()
appScope.release()
}
}
2.2 Job树形结构与父子关系
2.2.1 Job状态机模型

2.2.2 父子关系源码实现
kotlin
// JobSupport.kt#L1200
private fun addChildInternal(child: ChildHandleNode) {
loop@ while (true) {
val state = this.state
when (state) {
is Empty -> {
// 初始化状态
if (updateState(state, ChildList(child)))
break@loop
}
is ChildList -> {
// 添加子节点到链表
val newList = state.list.addChild(child)
if (updateState(state, newList))
break@loop
}
is Finishing -> {
// 正在结束状态,通知子Job取消
child.parentCancelled(state.rootCause)
break@loop
}
else -> {
// 已完成状态,子Job直接取消
child.parentCancelled((state as? CompletedExceptionally)?.cause)
break@loop
}
}
}
}
// 原子更新状态
private fun updateState(expect: Any?, update: Any?): Boolean {
return _state.compareAndSet(expect, update)
}
父子关系关键点:
- 原子操作:CAS保证线程安全
- 链表结构 :
ChildList
维护子Job链表 - 状态传播:父Job取消时遍历通知所有子Job
- 异常传递 :子Job异常通过
ChildHandle
上报
2.2.3 结构化并发优势
scss
// 非结构化并发(危险!)
fun startTasks() {
// 任务1:无关联
GlobalScope.launch { task1() }
// 任务2:无关联
launch(Job()) { task2() } // 独立的Job
// 问题:无法统一取消,可能导致泄漏
}
// 结构化并发(推荐)
fun startSafeTasks() {
coroutineScope {
launch { task1() } // 子协程1
launch { task2() } // 子协程2
// 所有子任务完成后才会继续
}
// 作用域外自动取消所有子任务
}
结构化优势对比表:
特性 | 非结构化 | 结构化 |
---|---|---|
取消传播 | ❌ 手动管理 | ✅ 自动传播 |
异常处理 | ❌ 容易丢失 | ✅ 统一处理 |
生命周期 | ❌ 容易泄漏 | ✅ 自动绑定 |
代码可读性 | ❌ 分散管理 | ✅ 逻辑集中 |
2.3 取消与异常传播机制
2.3.1 取消操作全流程

2.3.2 协作式取消实现
kotlin
// 可取消任务示例
suspend fun processLargeFile() {
val inputStream = FileInputStream("largefile.bin")
try {
val buffer = ByteArray(8192)
while (isActive) { // 检查活动状态
val bytesRead = withContext(Dispatchers.IO) {
inputStream.read(buffer)
}
if (bytesRead <= 0) break
// 处理数据...
}
} finally {
withContext(NonCancellable) {
inputStream.close() // 确保资源关闭
log("Stream closed safely")
}
}
}
// ViewModel中使用
fun startProcessing() {
viewModelScope.launch {
val job = launch { processLargeFile() }
// 5秒后取消
delay(5000)
job.cancel("Timeout exceeded")
}
}
2.3.3 异常传播机制源码
kotlin
// JobSupport.kt#L1400
private fun handleJobException(exception: Throwable): Boolean {
// 1. 尝试通过处理器处理
val handled = handleException(exception)
// 2. 未处理则传播给父Job
if (!handled) {
parent?.handleChildException(exception)?.let { return it }
}
// 3. 全局处理
if (!handled) {
handleUncaughtException(exception)
}
return true
}
// SupervisorJob的特殊处理
override fun handleChildException(exception: Throwable): Boolean {
// 不传播给父级
return false
}
异常传播路径:
- 当前Job的异常处理器
- 父Job的
handleChildException
- 当前线程的未捕获异常处理器
- 全局
CoroutineExceptionHandler
2.4 Android生命周期整合
2.4.1 lifecycleScope深度解析
kotlin
// LifecycleController.kt
internal class LifecycleController(
private val lifecycle: Lifecycle,
private val minState: State,
private val dispatchQueue: DispatchQueue
) {
private val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_DESTROY) {
// 销毁时取消所有协程
handleDestroy()
}
}
init {
// 安全注册观察者
if (lifecycle.currentState == Lifecycle.State.DESTROYED) {
handleDestroy()
} else {
lifecycle.addObserver(observer)
}
}
private fun handleDestroy() {
dispatchQueue.cancel()
lifecycle.removeObserver(observer)
}
}
核心流程:
- 创建时绑定生命周期观察者
- ON_DESTROY事件触发作用域取消
- 移除观察者防止内存泄漏
2.4.2 生命周期感知协程构建器
kotlin
// 自定义lifecycleScope扩展
fun LifecycleOwner.launchWhenCreated(
block: suspend CoroutineScope.() -> Unit
): Job = lifecycleScope.launch {
// 等待ON_CREATE状态
lifecycle.whenCreated(block)
}
// 状态等待实现
suspend fun Lifecycle.whenCreated(block: suspend CoroutineScope.() -> Unit) {
if (currentState >= Lifecycle.State.CREATED) {
block()
} else {
// 挂起等待目标状态
suspendCancellableCoroutine { cont ->
val observer = object : LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Event) {
if (event == Event.ON_CREATE) {
source.lifecycle.removeObserver(this)
cont.resume(Unit)
} else if (event == Event.ON_DESTROY) {
cont.cancel("Lifecycle destroyed before reaching CREATED")
}
}
}
addObserver(observer)
cont.invokeOnCancellation { removeObserver(observer) }
}
block()
}
}
2.5 全局异常处理策略
2.5.1 异常处理器金字塔

2.5.2 实现崩溃监控系统
kotlin
class CrashMonitor : CoroutineExceptionHandler {
override val key = CoroutineExceptionHandler
override fun handleException(context: CoroutineContext, exception: Throwable) {
// 1. 记录崩溃信息
val job = context[Job]?.let { "Job: ${it.key}" } ?: "Unknown job"
val coroutineName = context[CoroutineName]?.name ?: "unnamed"
// 2. 上报到服务器
FirebaseCrashlytics.getInstance().apply {
log("Coroutine crash in $coroutineName ($job)")
recordException(exception)
}
// 3. 主线程展示用户提示
Handler(Looper.getMainLooper()).post {
Toast.makeText(appContext, "操作失败,请重试", Toast.LENGTH_SHORT).show()
}
}
}
// 全局安装
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
// 设置全局处理器
Thread.setDefaultUncaughtExceptionHandler { thread, ex ->
if (ex is CompletionHandlerException) {
// 处理未捕获的协程异常
CrashMonitor().handleException(EmptyCoroutineContext, ex.cause!!)
} else {
// 处理普通线程异常
FirebaseCrashlytics.getInstance().recordException(ex)
}
}
}
}
// 在作用域中使用
viewModelScope.launch(CrashMonitor()) {
// 可能抛出异常的操作
}
本章小结
本章深入解析了结构化并发的核心机制:
- 作用域体系 :从
ViewModelScope
到自定义作用域 - Job树结构:父子关系与状态传播源码实现
- 取消机制:协作式取消与资源清理
- 异常传播:从子协程到全局处理器的完整路径
- 生命周期集成:Android特有的作用域绑定
在下一章中,我们将深入探讨Channel的内部实现机制,包括无锁队列设计、通道类型差异以及Select表达式的底层原理,揭示协程间通信的高效实现方式。