【问题标题】:Thread of Dispatchers.IO coroutineDispatchers.IO 协程的线程
【发布时间】:2019-06-06 02:55:45
【问题描述】:

我正在学习 Android 中的协程。我有以下代码:

private val scope = CoroutineScope(Dispatchers.Main + job)

operator fun invoke(token: String, callback: TaskCallback) {
    scope.launch {
        withContext(Dispatchers.IO) { userDataSource.saveApiToken(token) }
        callback.onCompleted()
    }
}

我预计 userDataSource.saveApiToken(token) 将从单独的线程中调用,但它在主线程上运行(Looper.myLooper() == Looper.getMainLooper() 在方法内返回 true)。 可能是什么原因? [我的错误]

我正在使用 Kotlin 插件版本:1.3.11-release-Studio3.2-1 和以下依赖项:kotlinx-coroutines-core:1.0.1 和 kotlinx-coroutines-android:1.0.1

【问题讨论】:

  • Thread.currentThread() 返回的是什么?
  • 返回线程[main,5,main]
  • 能否请您查看这里的主题withContext(Dispatchers.IO) { Thread.currentThread() }
  • 我刚刚测试过,有一个不同的线程:Thread[DefaultDispatcher-worker-1,5,main]
  • 当您的自定义 API 再次具有 TaskCallback 时,我看不出使用协程的意义。协程用于删除回调。您现在拥有的代码可以在没有它们的情况下以几乎相同的形式重写。

标签: android kotlin kotlin-coroutines coroutine coroutinescope


【解决方案1】:

withContext(Dispatchers.IO) 块中的线程应该是后台线程。如果我们把日志放在那里:

operator fun invoke(token: String, callback: TaskCallback) {
    scope.launch {
        withContext(Dispatchers.IO) { Log.e("Log", "t: ${Thread.currentThread()}") }
        callback.onCompleted()
    }
}

我们将看到 Thread[DefaultDispatcher-worker-1,5,main]。所以线程是一个后台线程。 正如 @Marko Topolnik 在 cmets 中提到的,协程的主要目的是摆脱回调。请尝试重构您的代码并删除callback: TaskCallback

【讨论】: