louiscad
07/16/2018, 3:12 PMrunBlocking
as their body, never returning while the inner coroutine is run successfully?withoutclass
07/16/2018, 3:27 PMwithoutclass
07/16/2018, 3:27 PMwithoutclass
07/16/2018, 3:30 PMlouiscad
07/16/2018, 4:05 PMrunBlocking
block, and after it, and the one after doesn't show up while the one before the closing brace does. In some other tests, the issue doesn't appear though. What I added is a suspend fun
using suspendCancellableCoroutine
, but it resumes fine...dekans
07/16/2018, 4:21 PMrunblocking
call?
Your service/Activity might get killed by Android because you blocked it.withoutclass
07/16/2018, 5:49 PMlouiscad
07/16/2018, 7:00 PM@Test
annotated method in androidTest
source set of an Android library module.louiscad
07/16/2018, 7:00 PMdgngulcan
07/16/2018, 9:11 PMrunBlocking
body with @UiThreadTest
annotated functions.louiscad
07/17/2018, 7:59 AM@Test
fun reproduceRunBlockingBug() {
runBlocking {
runBlockingBug()
println("I will be printed!")
}
println("I should be printed, but I won't")
}
private suspend fun runBlockingBug() = suspendCancellableCoroutine<Unit> { cont ->
val job = Job(parent = cont.context[Job]!!)
launch(cont.context, parent = job) {
cont.resume(Unit)
}
}
@elizarov the same code works on try.kotl.in, but hangs on runBlocking
closing brace in android Junit testselizarov
07/17/2018, 8:53 AMjob
is a child of runBlocking
, so runBlocking
waits for it to complete but it will not. It works as expected if you just launch(cont.cotext)
without creating an interim job
object.louiscad
07/17/2018, 9:12 AMdekans
07/17/2018, 9:13 AMjoin()
elizarov
07/17/2018, 9:13 AMjob.cancel()
elizarov
07/17/2018, 9:14 AMval job = launch(cont.context) { ... }
.elizarov
07/17/2018, 9:14 AMcont.resume
louiscad
07/17/2018, 9:16 AMsuspend fun <T> withSkyFacingCheck(
zRef: Float,
aRef: Float,
useAvg: Boolean = true,
avgSamplingDurationMillis: Long = maxSamplingWindowDurationMillis,
block: suspend (SensorEventListener) -> T
) = suspendCancellableCoroutine<T> { cont ->
val job = Job(parent = cont.context[Job]!!)
val listener = SkyFacingCheckingSensorEventListener(zRef, aRef, useAvg, avgSamplingDurationMillis) {
cont.cancel(IllegalStateException("Device moved!"))
job.cancel()
}
launch(cont.context, parent = job) {
val result = block(listener)
cont.resume(result)
}
}
louiscad
07/17/2018, 9:17 AMjob
property a lateinit var
elizarov
07/17/2018, 9:17 AMlouiscad
07/17/2018, 9:22 AMjob.cancel()
with my previous approach is the safest option in regards to by the codebase examplelouiscad
07/17/2018, 9:23 AM