ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Kotlin CoroutineContext 详解

Kotlin CoroutineContext 详解 Kotlin CoroutineContext 详解CoroutineContext是 Kotlin 协程的核心基础设施它本质上是一个键值对的集合Map-like 结构用于承载协程运行所需的全部上下文信息。一、核心构成CoroutineContext由多个Element组成每个 Element 都是一个独立的上下文单元表格Element作用常见值Job协程的生命周期与取消句柄Job()、SupervisorJob()CoroutineDispatcher决定协程在哪个线程/线程池执行Dispatchers.Main、Dispatchers.IO、Dispatchers.DefaultCoroutineName调试时标识协程名称CoroutineName(Network)CoroutineExceptionHandler捕获未处理的异常CoroutineExceptionHandler { _, e - ... }CoroutineStart启动模式懒启动等CoroutineStart.LAZY二、组合机制运算符CoroutineContext 通过合并右侧覆盖左侧同名键kotlinval context Dispatchers.IO CoroutineName(DataLoader) SupervisorJob() // 等价于 // CoroutineContext [Dispatchers.IO, CoroutineName(DataLoader), SupervisorJob()]继承规则子协程默认继承父协程的CoroutineContext但可以通过参数覆盖特定元素。三、Android 中的四大 DispatcherkotlinDispatchers.Main // UI 线程主线程 Dispatchers.IO // 网络/文件 IO线程池64 或 CPU 核心数 Dispatchers.Default // CPU 密集型计算线程数 CPU 核心数 Dispatchers.Unconfined// 不限制挂起后在调用线程继续⚠️ 生产环境慎用典型使用场景kotlinclass MyViewModel : ViewModel() { // 方式1viewModelScope 已绑定 Main SupervisorJob fun loadData() { viewModelScope.launch { // 自动在 Main 线程 val result withContext(Dispatchers.IO) { // 切换到 IO 线程执行网络请求 repository.fetchData() } // 自动回到 Main 线程更新 UI uiState.value result } } // 方式2自定义 Scope需要手动管理生命周期 private val customScope CoroutineScope( Dispatchers.Main SupervisorJob() CoroutineExceptionHandler { _, e - Log.e(Coroutine, Unhandled: $e) } ) }四、Job vs SupervisorJob表格特性Job()SupervisorJob()取消传播子协程失败 → 父取消 → 所有兄弟取消子协程失败不影响兄弟适用场景紧密关联的任务独立运行的任务如多个并行请求kotlin// SupervisorJob 示例一个子协程崩溃另一个继续执行 val scope CoroutineScope(SupervisorJob() Dispatchers.Main) scope.launch { launch { throw RuntimeException(Crash A) // 仅自身失败 } launch { delay(100) println(B still running) // ✅ 正常执行 } }五、CoroutineExceptionHandler仅对顶层协程生效子协程异常会向上冒泡kotlinval handler CoroutineExceptionHandler { context, throwable - // 这里处理所有未捕获异常 FirebaseCrashlytics.recordException(throwable) } val scope CoroutineScope(Dispatchers.Main SupervisorJob() handler) scope.launch { throw IllegalStateException(Unhandled) // 会被 handler 捕获 }⚠️注意try/catch可以捕获子协程异常但CoroutineExceptionHandler只在协程树顶层或SupervisorJob下生效。六、常见误区Dispatchers不是线程本身而是线程调度器。withContext(Dispatchers.IO)只是切换调度器不会创建新协程。viewModelScope/lifecycleScope已预配置Dispatchers.Main SupervisorJob一般不需要重复指定 Dispatcher。GlobalScope没有生命周期管理在 Android 中不推荐使用。coroutineContext[Job]可以获取当前协程的 Job 实例用于手动取消或检查状态。七、完整示例自定义 Contextkotlinclass MainActivity : AppCompatActivity() { private val activityScope CoroutineScope( Dispatchers.Main.immediate // immediate 避免不必要的线程切换 SupervisorJob() CoroutineName(MainActivityScope) CoroutineExceptionHandler { _, e - Toast.makeText(this, Error: ${e.message}, Toast.LENGTH_SHORT).show() } ) override fun onDestroy() { super.onDestroy() activityScope.cancel() // 清理所有协程 } }总结CoroutineContext是协程的运行环境配置包理解它的组合规则和各个 Element 的作用是写出健壮 Android 协程代码的关键。
返回列表