kotlin协程和主要处理程序关系

时间:2017-06-12 11:48:25

标签: android kotlin coroutine anko

我正在使用以下代码段

 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毫秒期间,按钮保持按下状态,即使我在点击后立即释放按钮,然后我意识到当onClick方法结束时恢复按下状态,< / p>

我有一个原始的概念 coroutine是一个使用CPS将代码转换为回调样式函数的编译器魔法,如关注

delay(20000L,callback = { trace("blocking end ")})

所以我有以下问题

  1. 到底是谁以及何时实际调用回调(例如trace(“阻塞结束”))如果答案是主要的looper或某事(对于nodejs,也许是eventloop),我们是否应该调整协程的框架并让coroutine将事件放入队列?
  2. 说coroutine实际上是编译魔术,我们可以编写与上面的代码段相同的代码,它不触发ANR但保持20000L的按下状态吗?

1 个答案:

答案 0 :(得分:3)

您使用的是runBlocking,因为它会阻止在协程执行期间调用它的线程。在您的特定情况下,您使用runBlocking阻止您的UI线程。

您可以将runBlocking替换为launch(UI),以在UI线程上启动后台协程,而不会阻止UI线程。您可以在Guide to kotlinx.coroutinesGuide to UI programming with coroutines中详细了解使用协同程序的各种方法。