pni*_*zle 4 kotlin kotlin-coroutines coroutinescope
我有以下代码(伪代码)
fun onMapReady()
{
//do some stuff on current thread (main thread)
//get data from server
GlobalScope.launch(Dispatchers.IO){
getDataFromServer { result->
//update UI on main thread
launch(Dispatchers.Main){
updateUI(result) //BREAKPOINT HERE NEVER CALLED
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如评论所述,代码永远不会进入协程调度到主队列。但是,如果我明确使用GlobalScope.launch(Dispatchers.Main)而不是仅仅使用以下内容,则以下内容有效launch(Dispatchers.Main)
fun onMapReady()
{
//do some stuff on current thread (main thread)
//get data from server
GlobalScope.launch(Dispatchers.IO){
getDataFromServer { result->
//update UI on main thread
GlobalScope.launch(Dispatchers.Main){
updateUI(result) //BREAKPOINT HERE IS CALLED
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么第一种方法不起作用?
我认为这里的问题是getDataFromServer()异步的,它立即返回,因此您launch(Dispatchers.Main)在退出GlobalScope.launch(Dispatchers.IO) { ... }块后调用。换句话说:您尝试使用已经完成的协程范围来启动协程。
我的建议是不要将异步、基于回调的 API 与这样的协程混合在一起。协程与同步挂起函数配合使用效果最佳。另外,如果您更喜欢异步执行所有内容并独立于其他任务(您onMapReady()启动了 3 个单独的异步操作),那么我认为协程根本不是一个好的选择。
谈到你的例子:你确定你不能getDataFromServer()直接从主线程执行吗?它不应该阻塞主线程,因为它是异步的。同样,在某些库中,回调会在主线程中自动执行,在这种情况下,您的示例可以替换为:
fun onMapReady() {
getDataFromServer { result->
updateUI(result)
}
}
Run Code Online (Sandbox Code Playgroud)
如果结果在后台线程中执行,那么您可以GlobalScope.launch(Dispatchers.Main)像以前一样使用,但这并不是我们使用协程的常用方式。或者您可以在 Android 上使用runOnUiThread()等实用程序,这可能更有意义。
| 归档时间: |
|
| 查看次数: |
4444 次 |
| 最近记录: |