当我从远程服务器提取数据时,我是否总是将 withContext(Dispatchers.IO) 添加到挂起状态?

Hel*_*oCW 6 kotlin kotlin-coroutines

我正在学习 Kotlin 的协程。

以下内容来自文章https://developer.android.com/kotlin/coroutines

重要提示:使用 suspend 不会告诉 Kotlin 在后台线程上运行函数。挂起函数在主线程上运行是正常的。在主线程上启动协程也很常见。当您需要主要安全时,您应该始终在挂起函数中使用 withContext(),例如读取或写入磁盘、执行网络操作或运行 CPU 密集型操作时。

通常,当我从远程服务器拉取数据时会花费很长时间,因此我需要在后台线程中放置“拉取数据功能”,以免冻结主 UI。

当我使用挂起从远程服务器提取数据时,我应该总是在挂起中添加 withContext(Dispatchers.IO) 吗?

顺便提一句,

代码 A 来自项目https://github.com/googlecodelabs/kotlin-coroutines,你可以看到

但是我在项目中找不到关键字withContext(),为什么?

代码 A

fun refreshTitle() = launchDataLoad {
    repository.refreshTitle()
}


private fun launchDataLoad(block: suspend () -> Unit): Unit {
    viewModelScope.launch {
        try {
            _spinner.value = true
            block()
        } catch (error: TitleRefreshError) {
            _snackBar.value = error.message
        } finally {
            _spinner.value = false
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Ens*_*lic 5

当我使用挂起从远程服务器提取数据时,我应该总是在挂起中添加 withContext(Dispatchers.IO) 吗?

这取决于。如果您使用像Retrofit 2.6.0这样的库对 具有本机支持suspend,则调度程序已经Dispatchers.IO(或库认为更合适的任何内容)。

如果从远程服务器获取数据呼叫阻塞,需要确保上运行它Dispatcher.IO与自己withContext(Dispatchers.IO)不阻塞主线程。

项目中找不到关键字withContext(),为什么?

因为项目使用 Retrofit,所以切换到Dispatchers.IO引擎盖下发生:https : //github.com/googlecodelabs/kotlin-coroutines/blob/master/coroutines-codelab/finished_code/src/main/java/com/example/android /kotlincoroutines/main/MainNetwork.kt

  • 我的观点是不同的:许多用户的印象是您需要“Dispatchers.IO”来处理 _any_ IO,但根本没有意识到它的解决方法。 (3认同)
  • 请记住,使用“Dispatchers.IO”并不是一个好兆头,它是针对使用同步 IO 的遗留库的一种解决方法。它浪费资源并且不允许太多并行提取。一个好的 Android 库应该是主线程安全的,并且可以与任何调度程序一起使用。 (2认同)