上下文是什么
CoroutineContext是一组用于定义协程行为的元素,包括以下几部分:
@Test
fun `test coroutine context`() = runBlocking {
launch(Dispatchers.IO + CoroutineName("test")) {
println("thread: ${Thread.currentThread().name}")
}
}
协程的上下文 = 默认值 + 继承的CoroutineContext + 参数
@Test
fun `test coroutine context extend`() = runBlocking {
val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
println("handle exception: $throwable")
}
//scope有了新的CoroutineContext,和runBlocking不一样
val scope = CoroutineScope(Job() + Dispatchers.Main + coroutineExceptionHandler)
//job的CoroutineContext继承自scope,但是Job会是新的,每个协程都会有新的Job
val job = scope.launch(Dispatchers.IO) {
//新协程
}
}
由于传入协程构建器的参数优先级更高,所以job的调度器被覆盖,是Dispatchers.IO而不是父类的Dispatchers.Main
协程构建器有2种传播形式:
当一个协程由于一个异常而运行失败时,它会传播这个异常并传递给它的父级。接下来父级会进行下面几步操作:
@Test
fun `test exception handler`() = runBlocking {
val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
println("handle exception: $throwable")
}
val scope = CoroutineScope(Job())
//能捕获到异常
val job1 = scope.launch(coroutineExceptionHandler) {
launch {
throw IllegalArgumentException()
}
}
val job2 = scope.launch() {
//不能捕获到异常
launch(coroutineExceptionHandler) {
throw IllegalArgumentException()
}
}
}
class GlobeCoroutineExceptionHandler : CoroutineExceptionHandler {
override val key = CoroutineExceptionHandler
override fun handleException(context: CoroutineContext, exception: Throwable) {
Log.d("xxx", "unHandle exception: $exception")
}
}
然后再main目录下,新建resources/META-INF/services目录,然后新建kontlinx.coroutines.CoroutineExceptionHandler文件,内容为:
com.example.kotlincoroutine.GlobeCoroutineExceptionHandler
//取消与异常
/*
* 打印顺序为:
* section 3
* section 1
* section 2
* handle exception:ArithmeticException
*
* */
@Test
fun `test exception handler2`() = runBlocking {
val handler = CoroutineExceptionHandler { _, throwable ->
println("handle exception: $throwable")
}
val job = GlobalScope.launch(handler) {
launch {
try {
delay(Long.MAX_VALUE)
}finally {
withContext(NonCancellable){
println("section 1")
delay(100)
println("section 2")
}
}
}
launch {
delay(10)
println("section 3")
throw ArithmeticException()
}
}
job.join()
}
码字不易,求转发,求点在看,求关注,感谢!