使用withContext方法在Kotlin协程中尝试捕获

时间:2020-08-27 12:14:09

标签: android kotlin kotlin-coroutines

我在launchasync的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-ktxSupervisorJob的实现中导入的。

我应该在哪里放置try-catch块来处理IOException?

1 个答案:

答案 0 :(得分:2)

Kotlin协程中的

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)移入该函数,这样它是独立的,您可以从任何协程中自由调用它。