我的印象是,如果我使用 viewModelScope,它内部使用 SupervisorJob(),将保持第三个 launch { } 块运行并打印 API 3。但输出不一样?为什么会出现这种情况?
class HomeViewModel : ViewModel() {
private val _text = MutableLiveData<String>().apply {
value = "This is home Fragment"
}
val text: LiveData<String> = _text
val handler = CoroutineExceptionHandler { _, exception ->
println("API exception caught: $exception")
exception.printStackTrace()
}
fun test() {
viewModelScope.launch(handler) {
launch {
println("API 1 launch executing")
apiCall("API 1", 1000)
}
launch {
println("API 2 launch executing")
delay(1500)
throw NullPointerException("Exception")
}
launch {
println("API 3 launch executing")
apiCall("API 3", 2000)
}
delay(4000)
println("API no api its ended.")
}
}
private suspend fun apiCall(message: String, time: Long) {
delay(time)
println(message)
}
}
输出:
16:08:50.314 I API 1 launch executing
16:08:50.314 I API 2 launch executing
16:08:50.314 I API 3 launch executing
16:08:51.317 I API 1
16:08:51.819 I API exception caught: java.lang.NullPointerException: Exception
您的三个并行协程都是单父协程的子级,因为您使用其范围来启动它们。父协程的作用域是
viewModelScope
的子级,并且不是主管,因此子协程不能独立失败。
直接从
viewModeScope
启动每个并行协程,或者用 supervisorScope
包装三个并行协程,以创建一个本地主管来将它们作为子进程启动。