У меня есть следующий фрагмент
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 появляется после # 1 в течение 20000L мс, и в диалоговом окне ANR не отображается
но происходили странные вещи: в течение 20000L мс кнопка удерживала нажатое состояние, даже когда я отпускал кнопку сразу после щелчка, затем я понял, что нажатое состояние восстанавливается, когда метод onClick заканчивается,
У меня была необработанная концепция, что сопрограмма - это магия компилятора, использующая CPS для преобразования кода в функцию стиля обратного вызова, например,
delay(20000L,callback = { trace("blocking end ")})
так что у меня есть следующие вопросы
- в конце концов, кто и когда на самом деле вызывает обратный вызов (например, трассировка ("блокирующий конец")), если ответ - это основной цикл или что-то в этом роде (для nodejs, возможно, цикл событий), должны ли мы адаптировать структуру для сопрограммы и позволить сопрограмме помещать событие в очередь?
- говоря, что сопрограмма на самом деле является магией компилятора, можем ли мы написать тот же код, что и приведенный выше фрагмент, который не запускает ANR, но сохраняет нажатое состояние для 20000L?
runBlocking
создает сопрограмму, которая выполняется в том же потоке, в котором она вызывается, и блокирует поток в точках приостановки. Поэтому вызовdelay
просто блокирует поток, в котором выполняетсяonClick
-функция. - person marstran   schedule 12.06.2017delay
в сочетании сrunBlocking
из потока пользовательского интерфейса. Либо переместите его в другой поток, вызвавlaunch(CommonPool)
, либо не вызывайтеdelay
. - person xap4o   schedule 12.06.2017