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.resumelouiscad
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 varelizarov
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