随着Java程序员长期迁移到Kotlin,我一直在努力围绕协程。总的来说,我认为我现在对它们已经有了很好的了解,但是后来我遇到了这样的情况……
我感觉是协程的经典用法:在不阻塞UI线程的情况下执行长时间运行的操作。我的代码结构如下:
fun updateUI() {
CoroutineScope(Dispatchers.Main).launch {
doUpdate()
// update the UI with results of doUpdate()
}
}
和
suspend fun doUpdate() =
withContext(Dispatchers.Default) {
// long-running operations here
}
...在主(UI)线程上调用updateUI
。
在我的开发环境中以交互方式运行它,似乎可以按预期工作-UI线程未阻塞,也未报告ANR。
但是,我的Play控制台正在报告此代码的ANR:
"main" prio=5 tid=1 Runnable
| group="main" sCount=0 dsCount=0 obj=0x75eb4268 self=0xa8784e00
| sysTid=4957 nice=0 cgrp=default sched=0/0 handle=0xab948534
| state=R schedstat=( 178941824 76636302 233 ) utm=6 stm=11 core=1 HZ=100
| stack=0xbe61c000-0xbe61e000 stackSize=8MB
| held mutexes= "mutator lock"(shared held)
at com.mypackage.ClassName.doUpdate (ClassName.java:66)
- locked <0x04706efb> (a com.mypackage.ClassName)
at com.mypackage.ClassName$updateUI$1.invokeSuspend (ClassName.java:149)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (BaseContinuationImpl.java:33)
at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.java:241)
at android.os.Handler.handleCallback (Handler.java:751)
at android.os.Handler.dispatchMessage (Handler.java:95)
at android.os.Looper.loop (Looper.java:154)
at android.app.ActivityThread.main (ActivityThread.java:6823)
at java.lang.reflect.Method.invoke! (Native method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1451)
具有更多协程经验的人可以对此提供任何见解吗?