我有以下片段
verticalLayout {
gravity = Gravity.CENTER
button("BUTTON").onClick {
trace("click on process")
runBlocking {
trace("blocking start") // #1
delay(20000L) #2
trace("blocking end") // #3
}
trace("click process end")
}
}
trace 是一个定义为实用函数的函数,用于使用具有当前线程名称的 Log.e 注销消息
当我单击按钮时,所有代码都按预期运行,并且日志显示在主线程日志中调用了所有跟踪函数,因为 #3 在 20000L 毫秒内出现在 #1 之后,并且没有显示 ANR 对话框
但奇怪的事情发生了,在 20000L ms 期间,即使我在单击后立即释放按钮,按钮仍保持按下状态,然后我意识到当 onClick 方法结束时恢复按下状态,
我有一个原始概念,协程是一种编译器魔法,使用 CPS 将代码转换为回调样式函数,如跟随
delay(20000L,callback = { trace("blocking end ")})
所以我有以下问题
- 最后谁和什么时候真正调用回调(例如trace(“blocking end”))如果答案是主循环器或其他东西(对于nodejs,可能是事件循环),我们是否应该为协程调整框架并让协程放置事件排队?
- 说协程实际上是编译器的魔法,我们可以编写与上面的代码片段相同的代码,它不会触发 ANR,而是保持 20000L 的按下状态?