在不阻塞主线程的情况下等待协程结果

Waiting for coroutine result without blocking main thread

我必须根据网络调用返回的数据更新片段中的项目。我不想阻塞主线程并以 ANR 结束所以我采用了“回调”的方法但是我想知道是否有一种方法可以等待网络调用的结果而不依赖使用协程的回调机制

当前实施

MyFragment.kt

fun updateButtonText() {
   handlerClass.getData {
      //received data from the server update the button text
   }
}

HandlerClass.kt

fun getData(callback: (String) -> Unit) {
   scope.launch(Dispatchers.IO) {
      val data = mySuspendedNetworkcallMethod()

      callback.invoke(data)
   }
}

期望的实现:

MyFragment.kt

fun updateButtonText() {
   val data = handlerClass.getData()
   button.text = data
}

HandlerClass.kt

suspend fun getData() {
   return mySuspendedNetworkcallMethod()
}

据我所知,对于所需的演示实现,我必须使用 runBlocking{} 来调用挂起的方法,但是 runBlocking{} 将阻止调用线程 - 在这种情况下将是主线程,直到 getData() returns 数据.

我不想阻塞主线程,但仍然可以调用并等待挂起的方法获取数据,然后更新按钮。

推荐的方法是将 viewmodel 和 viewmodelscope 用于挂起函数。

但是在您的情况下,只需使用 lifecyclescope

    fun updateButtonText() {
       lifecycleScope.launch{
          val data = handlerClass.getData()
          button.text = data
       }
    }

https://developer.android.com/topic/libraries/architecture/coroutines

协程旨在摆脱回调。您可以在 Fragment class 中使用 lifecycleScope 来启动一个 lifecycle-aware 协程,它将如下所示:

MyFragment.kt:

fun updateButtonText() = lifecycleScope.launch {
   button.text = handlerClass.getData()
}

HandlerClass.kt:

suspend fun getData() {
   return mySuspendedNetworkcallMethod()
}

如果您使用 MVVM 方法,您应该考虑使用 ViewModel 并且它是 viewModelScope 启动协程的扩展。

对于 LifecycleScope,请使用 androidx.lifecycle:lifecycle-runtime-ktx:2.4.0 或更高版本。

对于 ViewModelScope,使用 androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0 或更高。