kotlin 协程取消机制
2这个地方是获取挂起函数结果的地方,会判断是不是异常导致fail的,如果是就抛出异常,然后invokesuspend 方法结束,后面的代码不再执行(异常抛出是在suspend返回结果的时候)总结:协程取消机制,使用了throw exception 机制,抛出异常后,代码执行跳转到catch执行,不再执行后面代码。异常抛出是在suspend返回结果的时候,所以不要在suspend 函数外面try c
解决firebase 上的一个bug
requestLocationWithPermissions 是一个suspend 函数,页面destory 后,
searchPositionVm.mapController?.animateMyLocationMarker(location) 还执行,报错Can't access ViewModels from detached fragment
以下是修改好的,发现是try catch 但是没有重新抛出CancellationException
机制概述
Kotlin协程的取消机制基于异常抛出实现:当协程被取消时,会抛出CancellationException
异常。该异常被抛出后,代码执行流将立即跳转到最近的catch块,后续代码不再执行。
源码执行流程分析
1. 挂起函数恢复执行点
在suspend fun cc
函数中,挂起函数恢复执行的关键位置是resumeWith
方法调用处,这是协程恢复执行的入口。
2. 结果获取与异常判断
在获取挂起函数返回结果时,系统会检查结果是否为异常导致的失败:
-
如果是异常情况,直接抛出异常
-
invokeSuspend
方法随即结束,后续代码不再执行 -
异常抛出实际发生在suspend函数返回结果时
3. 异常捕获与传递
外层try-catch块会捕获异常并进行封装,然后将异常传递给父协程,形成异常传播链。
4. 取消状态检查
在执行过程中,会先检查协程是否已被取消:
-
如果已取消,则调用
continuation.resumeWithStackTrace(cause)
-
此机制确保取消信号能正确传递
关键实现点
异常的实际生成发生在DispatchedTask.run()
方法中。Job取消时,取消事件从父协程向子协程逐层传递。
重要结论与最佳实践
不要在suspend函数外部使用try-catch捕获所有异常,因为这会:
-
意外捕获
CancellationException
-
将异常转换为result.success结果
-
破坏异常向上传递的机制
-
影响协程正常的取消流程
建议仅在明确需要处理非取消异常时,在suspend函数内部使用try-catch,且应重新抛出CancellationException
。
更多推荐
所有评论(0)