.join() 方法阻塞 UI 线程,即使在新线程上调用时也是如此

The .join() method block UI thread even when called on a new thread

我正在编写一个需要在线检索数据的 kotin 应用程序。 使用 async(Dispatcher.IO) 从服务器获取结果和

val variable1 = async(Dispatchers.IO) {
                         delay(10000)
                         "I am the guy who comes 10 secs later\nDid you miss me?"
                      }

使用variable1.join()等待如下所示的结果:

@ExperimentalCoroutinesApi
    fun btn(view: android.view.View) {
        binding.firstText.text = ""
        runBlocking {
            launch(Dispatchers.IO) {
                //runOnUiThread { pop = popUp() }
                val variable1 = async(Dispatchers.IO) {
                    delay(10000)
                    "I am the guy who comes 10 secs later\nDid you miss me?"
                }
                variable1.join()
                val a = variable1.await()
                Log.d(TAG, "btn: ******************************************************* $a")
                runOnUiThread {
                    //binding.firstText.text = a
                }
            }
        }
    }

我在异步获取结果时遇到问题,variable1 一直阻塞 UI 线程。 据我了解,.join() 在执行之前等待结果。但问题是它会阻塞 UI 线程,即使它不在主线程上 运行 也是如此。 我应该如何更好地完成这项任务?谢谢。

由于我没有看到任何阻止操作的证据,这就是您所需要的:

fun btn(view: android.view.View) {
    binding.firstText.text = ""
    viewModelScope.launch {
        delay(10_000)
        val a = "I am the guy who comes 10 secs later\nDid you miss me?"
        Log.d(TAG, "btn: $a")
        binding.firstText.text = a
    }
}

如果您确实打算进行阻塞操作而不是 delay(10_000),那么您可以添加:

fun btn(view: android.view.View) {
    binding.firstText.text = ""
    viewModelScope.launch {
        val a = withContext(Dispatchers.IO) {
            blockingOperation()
            "I am the guy who comes 10 secs later\nDid you miss me?"
        }
        Log.d(TAG, "btn: $a")
        binding.firstText.text = a
    }
}

请注意 viewModelScope,除非您在 ViewModel class 中,否则这将不起作用。您可以使用 GlobalScope 来尝试,但这不是一个具有生产价值的解决方案,因为当您在之前的操作正在进行时触发许多此类操作时,它会导致运行时内存泄漏(它们将是因为没有什么可以取消它们)。