У меня есть следующий код:
import kotlin.coroutines.*;
import kotlinx.coroutines.*;
val job = SupervisorJob()
val handler = CoroutineExceptionHandler { _, e ->
println("Catch: $e")
}
val coroutineContext: CoroutineContext = Dispatchers.IO + job + handler
fun main() {
val job1 = GlobalScope.launch(coroutineContext) {
// supervisorScope {
launch {
println("Test0")
for (i in 0..5) {
println("Working! Iteration: $i")
delay(1000)
}
println("Test0 end")
}
launch {
println("Test1")
delay(2000)
throw IllegalAccessException()
}
launch {
println("Test2")
delay(3000)
println("Test2 end")
}
}
//}
runBlocking { job1.join() }
println("Test3")
}
Как видите, я использую SupervisorJob
, передавая его в coroutineContext
в GlobalScope.launch
, чтобы избежать отмены любых дочерних элементов в случае ошибки, если это произошло где угодно, и ошибка должна быть обработана в handler
. Далее в документации говорится о SupervisorJob
:
Creates a supervisor job object in an active state. Children of a supervisor job can fail independently of each other.
Исходя из этого, я ожидаю что-то подобное:
Test0
Working! Iteration: 0
Test1
Test2
Working! Iteration: 1
Catch: java.lang.IllegalAccessException
Working! Iteration: 2
Working! Iteration: 3
Test2 end
Working! Iteration: 4
Working! Iteration: 5
Test0 end
Test3
Но я получаю:
Test2
Test0
Working! Iteration: 0
Test1
Working! Iteration: 1
Catch: java.lang.IllegalAccessException
Test3
Единственное, что помогает, это раскомментировать supervisorScope
в приведенном выше коде.
Что я делаю не так? Как я могу установить ожидаемое поведение глобально в ViewModel
, например, чтобы избежать переноса каждого launch
в supervisorScope
?
Заранее спасибо.