我必须根据网络调用返回的数据更新片段中的项目。我不想阻塞主线程并最终使用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()
返回数据。
我不想阻塞主线程,但仍然可以调用&等待挂起的方法获取数据,然后更新按钮
推论的设计目的是消除回调。您可以在Fragment
类中使用lifecycleScope
来启动一个生命周期感知的协同程序,它看起来如下:
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
或更高版本。
推荐的方法是使用viewmodel和viewmodelscope来挂起函数。
然而,在您的情况下,只需使用lifecyclescope
fun updateButtonText() {
lifecycleScope.launch{
val data = handlerClass.getData()
button.text = data
}
}
https://developer.android.com/topic/libraries/architecture/coroutines