Kotlin suspendCancellCoroutine 笔记

suspendCancellableCoroutine 是 Kotlin 协程提供的一个底层挂起函数,用于将基于回调的异步 API 封装为挂起函数,同时支持协程的取消机制 。它比 suspendCoroutine 更强大,因为它允许在协程被取消时清理资源或停止正在进行的操作。


1. 作用

  • 桥接回调式 API :将传统的回调(如 onSuccess/onFailure)转换为挂起函数,让调用方可以用同步风格写异步代码。
  • 响应取消 :当启动协程的协程作用域被取消时,suspendCancellableCoroutine 可以感知取消事件,并执行清理操作(如关闭网络连接、取消异步任务),避免资源泄漏。

2. 函数签名

kotlin 复制代码
suspend fun <T> suspendCancellableCoroutine(
    block: (CancellableContinuation<T>) -> Unit
): T
  • 它挂起当前协程,直到通过 continuation.resume(...)continuation.resumeWithException(...) 恢复。
  • 参数 block 接收一个 CancellableContinuation<T> 对象,该对象除了提供 resume 方法外,还增加了取消相关的功能。

3. 与 suspendCoroutine 的区别

特性 suspendCoroutine suspendCancellableCoroutine
取消监听 ❌ 无法感知协程取消 ✅ 可以注册取消回调
资源清理 ❌ 需要手动处理(如用 finally ✅ 在取消回调中安全释放资源
并发处理 基础功能 额外提供原子性操作(如 invokeOnCancellation

4. 典型用法

示例:将回调式 API 封装为挂起函数

假设有一个基于回调的网络请求:

kotlin 复制代码
interface Callback {
    fun onSuccess(result: String)
    fun onFailure(error: Throwable)
}

fun makeRequest(callback: Callback) {
    // 模拟异步请求
    Thread.sleep(1000)
    callback.onSuccess("Data")
}

使用 suspendCancellableCoroutine 封装:

kotlin 复制代码
suspend fun fetchData(): String = suspendCancellableCoroutine { continuation ->
    makeRequest(object : Callback {
        override fun onSuccess(result: String) {
            // 恢复协程,返回结果
            continuation.resume(result)
        }
        override fun onFailure(error: Throwable) {
            // 恢复协程并抛出异常
            continuation.resumeWithException(error)
        }
    })

    // 注册取消回调:如果协程被取消,可以取消请求
    continuation.invokeOnCancellation {
        // 清理资源,例如取消网络请求、关闭流等
        cancelRequest()
    }
}

取消处理的关键点

  • invokeOnCancellation:注册一个回调,当协程被取消时执行。通常在这里释放资源或取消底层操作。
  • 如果底层 API 本身支持取消(如返回一个 Cancellable 对象),可以在这里调用其取消方法。

5. 注意事项

  • 原子性恢复CancellableContinuation 提供了 resume 的原子性保证,但开发者仍需确保不要重复调用 resume
  • 已取消状态的检查 :在调用 resume 前,可以使用 continuation.isActive 判断协程是否仍处于活跃状态,避免不必要的操作。
  • 取消传播 :如果协程被取消,挂起点会抛出 CancellationException,调用方需要适当处理(通常由上层协程作用域统一处理)。

6. 高级功能

  • 不可取消的挂起 :如果确实不需要取消,或者无法响应取消,可以使用 suspendCoroutine。但通常推荐使用 suspendCancellableCoroutine 以提供更好的协作式取消。
  • 调用栈信息CancellableContinuation 还保留了挂起点的调用栈,便于调试。

总结

suspendCancellableCoroutine 是编写自定义挂起函数的核心工具,尤其适用于需要与取消机制协同工作的回调式 API。通过它,你可以将任何异步操作无缝集成到 Kotlin 协程的取消体系中,实现资源的安全管理和高效的并发控制。

相关推荐
嗷o嗷o19 分钟前
Android BLE 里,MTU、分包和长数据发送到底该怎么处理
android
Gary Studio2 小时前
Android AIDL HAL工程结构示例
android
y = xⁿ2 小时前
MySQL八股知识合集
android·mysql·adb
andr_gale3 小时前
04_rc文件语法规则
android·framework·aosp
祖国的好青年4 小时前
VS Code 搭建 React Native 开发环境(Windows 实战指南)
android·windows·react native·react.js
黄林晴4 小时前
警惕!AGP 9.2 别只改版本号,R8 规则与构建链路全线收紧
android·gradle
小米渣的逆袭5 小时前
Android ADB 完全使用指南
android·adb
儿歌八万首5 小时前
Jetpack Compose Canvas 进阶:结合 animateFloatAsState 让自定义图形动起来
android·动画·compose
zhangphil6 小时前
Android Page 3 Flow读sql数据库媒体文件,Kotlin
android·kotlin