kotlin: CoroutineExceptionHandler协程异常处理器

一,CoroutineExceptionHandler不同的用法

统一给父协程定义一个 CoroutineExceptionHandler,
如果一个子协程异常了,其他子协程也不需要继续的话就采用 coroutineScope 方法,默认的 Job 就是这种表现,
如果一个子协程异常了,其他子协程还需要继续的话就采用 supervisorScope 方法,
或者创建协程作用域的时候传入带 SupervisorJob() 函数返回的特殊 Job 的协程上下文
 

二,例一:用supervisorScope启动协程

代码:
        //处理按钮点击事件
        binding.button1.setOnClickListener {
            runBlocking {
                //定义异常处理
                val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
                    //CoroutineExceptionHandler#handleException 方法回调
                    println("这里是exceptionHandler:协程:"+"${coroutineContext[CoroutineName].toString()} 捕捉到异常 :$throwable")
                }
                launch(exceptionHandler) {    //传递给父协程
                    supervisorScope {
                        launch(CoroutineName("异常子协程")) {
                            println("${Thread.currentThread().name}:"+"我要开始抛异常了")
                            throw NullPointerException("空指针异常")
                        }
                        for (index in 0..10) {
                            launch(CoroutineName("子协程$index")) {
                                if (index %3 == 0){
                                    println("${Thread.currentThread().name}:"+"$index 将抛出异常")
                                    throw NullPointerException("子协程${index}空指针异常")
                                } else {
                                    println("${Thread.currentThread().name}正常执行:"+"$index")
                                }
                            }
                        }
                    }
                }

            }
        }
运行结果:
image

三,例二,CoroutineScope(SupervisorJob() + exceptionHandler) 方式启动协程

代码:
        //处理按钮点击事件
        binding.button2.setOnClickListener {
            runBlocking {
                //定义CoroutineExceptionHandler
                val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
                    //CoroutineExceptionHandler#handleException 方法回调
                    println("exceptionHandler:协程:"+"${coroutineContext[CoroutineName].toString()} 捕捉到异常 :$throwable")
                }
                //CoroutineScope 方法,
                //SupervisorJob 方法代表子协程会自己处理异常,并不会影响其兄弟协程或者父协程
                val supervisorScope = CoroutineScope(SupervisorJob() + exceptionHandler)
                with(supervisorScope) {
                    launch(CoroutineName("异常子协程")) {
                        println("${Thread.currentThread().name}:"+"我要开始抛异常了")
                        throw NullPointerException("空指针异常")
                    }
                    for (index in 0..10) {
                        launch(CoroutineName("子协程$index")) {
                            if (index % 3 == 0) {
                                println("${Thread.currentThread().name}:"+"$index 将抛出异常")
                                throw NullPointerException("子协程${index}空指针异常")
                            } else {
                                println("${Thread.currentThread().name}正常执行:"+"$index")
                            }
                        }
                    }
                }
            }
        }
 
运行结果:
image

四,例三,使用CoroutineScope时,一个子协程异常后其他子协程也不会继续

代码:
        //处理按钮点击事件
        binding.button3.setOnClickListener {
            runBlocking {
                //定义异常处理器
                val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
                    //CoroutineExceptionHandler#handleException 方法回调
                    println("exceptionHandler:协程:"+"${coroutineContext[CoroutineName].toString()} 捕捉到异常 :$throwable")
                }
                //CoroutineScope 方法,不再采用SupervisorJob
                val scope = CoroutineScope(exceptionHandler)
                with(scope) {
                            for (index in 0..10) {
                                launch(CoroutineName("子协程$index")) {
                                    if (index % 3 == 0) {
                                        println("${Thread.currentThread().name}:"+"$index 将抛出异常")
                                        throw NullPointerException("子协程${index}空指针异常")
                                    } else {
                                        println("${Thread.currentThread().name}正常执行:"+"$index")
                                    }
                                }
                            }
                }

            }
        }
 
运行结果:
image
 
 
posted @ 2025-08-09 13:40  刘宏缔的架构森林  阅读(25)  评论(0)    收藏  举报