ansman
08/26/2019, 12:37 AMDispatchers.Main.immediate
? yield()
will not do anything. delay(1)
works but is kind of uglyoctylFractal
08/26/2019, 12:42 AMDispatchers.Main
?ansman
08/26/2019, 12:42 AMstreetsofboston
08/26/2019, 12:43 AMpost
of a Runnable, but putting in front of the queue?octylFractal
08/26/2019, 12:43 AMwithContext(Dispatchers.Main)
then?ansman
08/26/2019, 12:44 AMsuspend fun defer() {
val dispatcher = coroutineContext[ContinuationInterceptor] as? CoroutineDispatcher
if (dispatcher == null) {
Timber.w("No coroutine dispatcher found, using delay instead")
delay(1)
} else {
suspendCancellableCoroutine { cont ->
dispatcher.dispatch(EmptyCoroutineContext, Runnable { cont.resume(Unit) })
}
}
}
streetsofboston
08/26/2019, 12:50 AMansman
08/26/2019, 12:51 AMstreetsofboston
08/26/2019, 12:55 AMdefer
is called on the main thread)?
I'd write something myself to make the synchronization you need more explicit instead of relying on delay or dispatcher.dispatch.ansman
08/26/2019, 12:55 AMdispatcher.dispatch
will always post it to the queue, even on the immediate dispatcherstreetsofboston
08/26/2019, 12:57 AMansman
08/26/2019, 12:58 AMviewCreatedScope.launch {
view.awaitPredraw()
// Setup animation
defer()
TransitionManager.beginDelayedTransition(...)
// Set to final state
}
octylFractal
08/26/2019, 1:00 AMimmediate
-- any suspend point that actually suspends will still re-dispatch, since coroutine suspension removes the code from the thread, and any point that doesn't suspend will continue in the same thread regardless of immediate
streetsofboston
08/26/2019, 1:00 AMoctylFractal
08/26/2019, 1:00 AMimmediate
only affects the initial coroutine launchansman
08/26/2019, 1:01 AMimmediate
since it would actually draw the frame where i want to set up the animationresumeWith
for a coroutine dispatcher:
override fun resumeWith(result: Result<T>) {
val context = continuation.context
val state = result.toState()
if (dispatcher.isDispatchNeeded(context)) {
_state = state
resumeMode = MODE_ATOMIC_DEFAULT
dispatcher.dispatch(context, this)
} else {
executeUnconfined(state, MODE_ATOMIC_DEFAULT) {
withCoroutineContext(this.context, countOrElement) {
continuation.resumeWith(result)
}
}
}
}
streetsofboston
08/26/2019, 1:03 AMpost
methods for sync, not relying on the Coroutine Dispatchers. You can the wrap that in a suspend function called defer()ansman
08/26/2019, 1:03 AMisDispatchNeeded
would return false
if called on the main thread when using the immediate dispatcherdefer
could pretty much only be called on the main threadstreetsofboston
08/26/2019, 1:05 AMpost
from any thread.ansman
08/26/2019, 1:05 AMdefer
streetsofboston
08/26/2019, 1:06 AMlouiscad
08/26/2019, 6:55 AMyield()
should support the immediate
dispatcher. You should open an issue on GitHub.David Glasser
08/26/2019, 7:04 PM