Kotlin Coroutines Exception

本文探讨了Kotlin协程中的异常处理,包括withContext、Async、coroutineScope + Async、supervisorScope + Async以及CancellationException的用法和它们在异常处理中的表现。重点介绍了协程如何处理CancellationException,并指出这种异常在调试中作为额外信息的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kotlin Coroutines Exception

官方文档:https://www.kotlincn.net/docs/reference/coroutines/exception-handling.html

kotlin coroutines的exception有几种容易混淆的处理情形,在这里列举一下:

withContext

GlobalScope.launch(Dispatchers.Main) {
    try {
        withContext(Dispatchers.IO) {
            Log.d("coroutine exception", "start to throw")
            throw java.lang.Exception("hahaha")
        }
    } catch (e : java.lang.Exception){
        Log.d("coroutine exception", "outside "+e.message)
    }
}

运行结果:

coroutine exception: start throw
coroutine exception: outside hahaha

Async

GlobalScope.launch(Dispatchers.Main) {
    try {
        async {
            Log.d("coroutine exception", "start throw")
            throw java.lang.Exception("hahaha")
        }.await()
    } catch (e : java.lang.Exception){
        Log.d("coroutine exception", "outside "+e.message)
    }
}

运行结果:

coroutine exception: start throw
coroutine exception: outside hahaha
App Crash!

coroutineScope + Async

GlobalScope.launch(Dispatchers.Main) {
    try {
        coroutineScope {
            try {
                async {
                    Log.d("coroutine exception", "start throw")
                    throw java.lang.Exception("hahaha")
                }.await()
            } catch (e : java.lang.Exception){
                Log.d("coroutine exception", "inside "+e.message)
            }

        }
    } catch (e: Exception) {
        Log.d("coroutine exception", "outside " + e.message)
    }
}

运行结果:

coroutine exception: start throw
coroutine exception: inside hahaha
coroutine exception: outside hahaha

supervisorScope + Async

GlobalScope.launch(Dispatchers.Main) {
    try {
        supervisorScope {
            try {
                async {
                    Log.d("coroutine exception", "start throw")
                    throw java.lang.Exception("hahaha")
                }.await()
            } catch (e : java.lang.Exception){
                Log.d("coroutine exception", "inside "+e.message)
            }

        }
    } catch (e: Exception) {
        Log.d("coroutine exception", e.message)
    }
}

运行结果:

coroutine exception: start throw
coroutine exception: inside hahaha

CancellationException

协程内部使用 CancellationException 来进行取消,这个异常会被所有的处理者忽略,所以那些可以被 catch 代码块捕获的异常仅仅应该被用来作为额外调试信息的资源。 当一个协程在没有任何理由的情况下使用 Job.cancel 取消的时候,它会被终止,但是它不会取消它的父协程。 无理由取消是父协程取消其子协程而非取消其自身的机制。

val job = launch {
    val child = launch {
        try {
            delay(Long.MAX_VALUE)
        } finally {
            println("Child is cancelled")
        }
    }
    yield()
    println("Cancelling child")
    child.cancel()
    child.join()
    yield()
    println("Parent is not cancelled")
}
job.join()

运行结果:

Cancelling child
Child is cancelled
Parent is not cancelled
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值