如何使 UI 调度程序立即恢复继续

How to make the UI dispatcher resume the continuation immediately

我一直在我的 Android 项目中大量使用协程。例如,我使用它们将阻塞调用和 CPU 密集型任务移交给线程池。这是 launch(UI) 完美工作的地方:它确保继续在 UI 线程上恢复。

我也在使用协同程序来处理诸如等待第一个 onDraw 调用、使用 postOnAnimate() 恢复动画循环等。在这些情况下,UI 上下文下降缺少我需要的东西,因为它通过向事件循环提交一个项目异步恢复继续,即使在 UI 线程上调用了 cont.resume()

在我等待对 ImageView 的第一个 onDraw 调用的情况下,这变得特别糟糕:我必须根据现在已知的视图尺寸重新定位图像。但是,由于协程异步恢复,onDraw() 完成,然后再 运行,然后我的协程才恢复。用户体验到闪烁是因为位置不正确的图像短暂出现。

是否有一个选项可以强制 UI 调度程序在 UI 线程上调用 cont.resume() 时立即恢复?

是的。您可以研究 awaitFrame 在 Adroind 上下文 here 中的实现并使用类似的技术。特别是,当使用 suspendCancellableCoroutine 函数暂停协程时,如果您已经 运行 在此调度程序的上下文中通过使用 resumeUndispatched 函数在生成的 CancellableContinuation 中。您必须提供对相应调度程序的引用作为 "proof" 并使用以下代码模式:

with(continuation) { dispatcher.resumeUndispatched(value) }

从某种意义上说,这种方法是安全的,如果您要恢复的协同程序使用不同的调度程序,那么它仍将被调度到适当的调度程序。只有在您指定的调度程序中 运行ning 时才会禁止调度。