我在launch
和async
的Kotlin协程中找到了一些有关异常处理的文档。但是我找不到解决withContext
的解决方案。
假设我有一个协程,例如:
fun bar(path: String) {
viewModelScope.launch {
val foo = withContext(Dispatchers.IO) {
foo(path)
}
}
}
fun foo(path: String) {
// do something...
val media = MediaMetadataRetriever()
media.setDataSource(path) // may throw IllegalArgumentException according to API's doc
return media.frameAtTime
}
viewModelScope
是使用lifecycle-viewmodel-ktx
从SupervisorJob
的实现中导入的。
我应该在哪里放置try-catch块来处理IOException?
答案 0 :(得分:2)
try-catch 感觉有些笨拙,但是我认为部分原因是Kotlin的设计师不认为您应该首先使用它。当某事物是检查异常(由程序员无法控制的事物引起)时,他们的建议是将其包装或返回null。例如:
fun foo(path: String): Bitmap? {
// do something...
val media = MediaMetadataRetriever()
try {
media.setDataSource(path)
catch (e: IOException) {
Log.e(TAG, "Failed to set media data source", e)
return null
}
return media.frameAtTime
}
fun bar(path: String) {
viewModelScope.launch {
val foo = withContext(Dispatchers.IO) {
foo(path)
}
if (foo == null) {
// show error to user or something
} else {
// do something with smart-cast non-null foo Bitmap
}
}
}
顺便说一句,对于您永远不会从主线程调用的foo
这样的阻塞函数,我建议将其设为suspend
函数并将withContext(Dispatchers.IO)
移入该函数,这样它是独立的,您可以从任何协程中自由调用它。