简体   繁体   中英

Waiting for coroutine result without blocking main thread

I've to update an item in a fragment based on the data returned from the.network call. I don't want to block the main thread and end up with ANR so I adopted the approach of "callbacks" however I wonder if there's a way to wait for the result from the.network call without relying on the callback mechanism using coroutines

Current implementation

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)
   }
}

Desired Implementation:

MyFragment.kt

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

HandlerClass.kt

suspend fun getData() {
   return mySuspendedNetworkcallMethod()
}

For the desired demo implementation, I understand, I'd have to use runBlocking{} to call a suspended method however runBlocking{} will block the calling thread - which in this case would be the Main Thread until getData() returns the data.

I don't want to block the main thread but still be able to cal & wait for the suspended method to fetch the data and then update the button.

Coroutines are designed to get rid of callbacks. You can use lifecycleScope in the Fragment class to launch a lifecycle-aware coroutine, it will look like the following:

MyFragment.kt :

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

HandlerClass.kt :

suspend fun getData() {
   return mySuspendedNetworkcallMethod()
}

If you use MVVM approach you should consider to use ViewModel and it's viewModelScope extension to launch coroutines.

For LifecycleScope , use androidx.lifecycle:lifecycle-runtime-ktx:2.4.0 or higher.

For ViewModelScope , use androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0 or higher.

Well recommended way is to use viewmodel and viewmodelscope for suspend functions.

However in your situation, just use lifecyclescope

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM