Kotlin 协程协程异常处理 ④ ( Android 协程中出现异常导致应用崩溃 | Android 协程中使用协程异常处理器捕获异常 | Android 全局异常处理器 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin 协程协程异常处理 ④ ( Android 协程中出现异常导致应用崩溃 | Android 协程中使用协程异常处理器捕获异常 | Android 全局异常处理器 )相关的知识,希望对你有一定的参考价值。
文章目录
一、android 协程中出现异常导致应用崩溃
在前几篇博客示例中 , 协程中 如果出现异常 , 没有进行捕获 , 则程序直接崩溃 , 这种情况下需要进行 异常的捕获 以 避免 Android 应用程序的崩溃 ;
示例代码 :
package kim.hsl.coroutine
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity()
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
GlobalScope.launch
Log.i(TAG, "验证协程中抛出异常")
throw IllegalArgumentException()
执行结果 : 在协程中抛出了异常 , 应用直接退出 ;
15:46:00.444 I 验证协程中抛出异常
15:46:00.486 D Skia GL Pipeline
15:46:00.504 E FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: kim.hsl.coroutine, PID: 26587
java.lang.IllegalArgumentException
at kim.hsl.coroutine.MainActivity$onCreate$1.invokeSuspend(MainActivity.kt:18)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
15:46:00.511 W Force finishing activity kim.hsl.coroutine/.MainActivity
15:46:00.528 I Sending signal. PID: 26587 SIG: 9
---------------------------- PROCESS ENDED (26587) for package kim.hsl.coroutine ----------------------------
二、Android 协程中使用协程异常处理器捕获异常
在 Android 程序中 , 可以使用 协程异常处理器 CoroutineExceptionHandler 捕获异常 , 将其实例对象传递给 launch 协程构建器 作为参数即可 ;
该参数作为 协程上下文 的 协程异常处理器 CoroutineExceptionHandler 元素 ;
代码示例 :
package kim.hsl.coroutine
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity()
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 创建 协程异常处理器 CoroutineExceptionHandler
val coroutineExceptionHandler = CoroutineExceptionHandler
coroutineContext, throwable ->
Log.i(TAG, "CoroutineExceptionHandler 中处理异常 " +
"\\n协程上下文 $coroutineContext" +
"\\n异常内容 $throwable")
GlobalScope.launch
Log.i(TAG, "验证协程中抛出异常")
throw IllegalArgumentException()
执行结果 : 协程异常处理器 CoroutineExceptionHandler 捕获到了异常 ;
15:47:54.749 I 验证协程中抛出异常
15:47:54.754 I CoroutineExceptionHandler 中处理异常
协程上下文 [kim.hsl.coroutine.MainActivity$onCreate$$inlined$CoroutineExceptionHandler$1@bc6a601, StandaloneCoroutineCancelling@fef2ca6, Dispatchers.Default]
异常内容 java.lang.IllegalArgumentException
三、Android 全局异常处理器
Android 中的 全局异常处理器 , 可以 获取 所有的 协程 中产生的 没有被捕获的异常 ;
- 无法阻止崩溃 : 全局异常处理器 不能捕获这些异常 进行处理 , 应用程序 还是要崩溃 ;
- 用于调试上报 : 全局异常处理器 仅用于 程序调试 和 异常上报 场景 , 也就是出现了异常 , 将异常通知开发者 ;
全局异常处理器使用步骤如下 :
① 在 app/main/ 目录下创建 resources 目录 , 在 resources 目录下创建 META-INF 目录 ,
② 在 META-INF 目录下创建 services 目录 ,
③ 在 app/main/resources/META-INF/services 目录下 , 创建 名称为 kotlinx.coroutines.CoroutineExceptionHandler 的文件 ;
④ 创建 协程的 全局异常处理器 MyCoroutineExceptionHandler 自定义类 , 需要 实现 CoroutineExceptionHandler 接口 ; 并覆盖接口中的 val key
成员变量 和 fun handleException(context: CoroutineContext, exception: Throwable)
成员方法 ;
package kim.hsl.coroutine
import android.util.Log
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlin.coroutines.CoroutineContext
class MyCoroutineExceptionHandler : CoroutineExceptionHandler
val TAG = "MyCoroutineExceptionHandler"
override val key = CoroutineExceptionHandler
override fun handleException(context: CoroutineContext, exception: Throwable)
Log.i(TAG, "在 MyCoroutineExceptionHandler 全局异常处理器 中处理未捕获异常 " +
"\\n协程上下文 $context" +
"\\n抛出异常 $exception")
⑤ 在 app/main/resources/META-INF/services/kotlinx.coroutines.CoroutineExceptionHandler 文件中配置 协程的 全局异常处理器 MyCoroutineExceptionHandler 自定义类 的全类名 kim.hsl.coroutine.MyCoroutineExceptionHandler
, 如下图所示 :
⑥ 在 Activity 中实现一个 抛出异常的协程 :
package kim.hsl.coroutine
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity()
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
GlobalScope.launch()
Log.i(TAG, "验证协程中抛出异常")
throw IllegalArgumentException()
⑦ 执行上述应用 , 会抛出异常 , 协程中也不进行异常处理 , 此时执行结果如下 :
16:30:53.537 I 验证协程中抛出异常
16:30:53.578 D Skia GL Pipeline
16:30:53.590 I 在 MyCoroutineExceptionHandler 全局异常处理器 中处理未捕获异常
协程上下文 [StandaloneCoroutineCancelling@8252a7e, Dispatchers.Default]
抛出异常 java.lang.IllegalArgumentException
16:30:53.593 E FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: kim.hsl.coroutine, PID: 8808
java.lang.IllegalArgumentException
at kim.hsl.coroutine.MainActivity$onCreate$1.invokeSuspend(MainActivity.kt:18)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
16:30:53.599 W Force finishing activity kim.hsl.coroutine/.MainActivity
16:30:53.608 I Sending signal. PID: 8808 SIG: 9
16:30:53.627 I Process kim.hsl.coroutine (pid 8808) has died: cch CRE
---------------------------- PROCESS ENDED (8808) for package kim.hsl.coroutine ----------------------------
在 MyCoroutineExceptionHandler 全局异常处理器 中处理未捕获异常 , 但是程序依然崩溃 , 可以在 全局异常处理器 中获取到异常信息 ;
以上是关于Kotlin 协程协程异常处理 ④ ( Android 协程中出现异常导致应用崩溃 | Android 协程中使用协程异常处理器捕获异常 | Android 全局异常处理器 )的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 协程协程异常处理 ② ( SupervisorJob 协程 | supervisorScope 协程作用域构建器函数 )
Kotlin 协程协程异常处理 ② ( SupervisorJob 协程 | supervisorScope 协程作用域构建器函数 )
Kotlin 协程协程异常处理 ③ ( 协程异常处理器 CoroutineExceptionHandler 捕获异常 | 验证 CoroutineScope 协程的异常捕捉示例 )
Kotlin 协程协程异常处理 ③ ( 协程异常处理器 CoroutineExceptionHandler 捕获异常 | 验证 CoroutineScope 协程的异常捕捉示例 )
Kotlin 协程协程异常处理 ① ( 根协程异常处理 | 自动传播异常 | 在协程体捕获异常 | 向用户暴露异常 | 在 await 处捕获异常 | 非根协程异常处理 | 异常传播特性 )
Kotlin 协程协程异常处理 ① ( 根协程异常处理 | 自动传播异常 | 在协程体捕获异常 | 向用户暴露异常 | 在 await 处捕获异常 | 非根协程异常处理 | 异常传播特性 )