我在Android项目中大量使用协同程序。例如,我使用它们将阻塞调用和CPU密集型任务移交给线程池。这是launch(UI)
完美运行的地方:它确保继续在UI线程上恢复。
我也在使用coroutines来等待第一次onDraw
调用,使用postOnAnimate()
恢复动画循环等等。在这些情况下,UI上下文不能满足我的需要,因为它通过向事件循环提交项来异步恢复延续,即使在UI线程上调用了cont.resume()
。
在等待onDraw
上的第一次ImageView
调用的情况下,这种情况变得特别糟糕:我必须根据现在已知的视图维度重新定位图像。然而,由于协同程序异步恢复,onDraw()
完成,然后再运行几次,然后我的协程才恢复。用户会出现闪烁,因为短暂出现的图像位置不正确。
是否有一个选项可以强制UI调度程序在UI线程上调用cont.resume()
时立即恢复?
答案 0 :(得分:1)
是。您可以在Adroind上下文here中学习awaitFrame
的实现,并使用类似的技巧。特别是,当使用suspendCancellableCoroutine
函数挂起协同程序时,如果您已通过resumeUndispatched
函数在此调度程序的上下文中运行,则可以要求恢复它 undispatched CancellableContinuation
。您必须提供对相应调度程序的引用作为“证明”,并使用以下代码模式:
with(continuation) { dispatcher.resumeUndispatched(value) }
这种方法在某种意义上是安全的,如果您正在恢复的协程使用不同的调度程序,那么它仍将被分派给适当的调度程序。仅当调度在您指定的调度程序中运行时,才会禁止调度。