Paul Woitaschek
01/18/2022, 9:42 PM/**
* This function returns once a shake was detected
*/
suspend fun detect() {
val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager?
?: awaitCancellation()
val shakeDetected = CompletableDeferred<Unit>()
val listener = SeismicShakeDetector.Listener {
shakeDetected.complete(Unit)
}
val shakeDetector = SeismicShakeDetector(listener)
try {
shakeDetector.start(sensorManager)
shakeDetected.await()
} finally {
shakeDetector.stop()
}
}
I’ve written this function that suspend until a shake was detected. Do you think such a usage of coroutines makes sense?
It feels kind of unintuitive in terms of ergonomics of a regular functionmkrussel
01/18/2022, 9:50 PMsuspendCancellableCoroutine
Correct solution doesn't handle cancelation correctly, and suspendCancellableCoroutine
already will handle the completable for you so it is a bit easier to use.Alex Vanyo
01/18/2022, 9:55 PMsuspendCancellableCoroutine
, which is the perfect tool for adapting a callback like this.Paul Woitaschek
01/18/2022, 10:02 PMsuspend fun detect() {
suspendCancellableCoroutine<Unit> { cont ->
val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager?
?: return@suspendCancellableCoroutine
val listener = SeismicShakeDetector.Listener {
cont.resume(Unit)
}
val shakeDetector = SeismicShakeDetector(listener)
shakeDetector.start(sensorManager)
cont.invokeOnCancellation {
shakeDetector.stop()
}
}
}
Made the code even easier 🙂mkrussel
01/18/2022, 10:05 PMPaul Woitaschek
01/18/2022, 10:09 PMmkrussel
01/18/2022, 10:11 PMPaul Woitaschek
01/18/2022, 10:15 PMNick Allen
01/18/2022, 11:14 PMA typical use of this function is to suspend a coroutine while waiting for a result from a single-shot callback API and to return the result to the caller. For multi-shot callback APIs see callbackFlow.The
callbackFlow
implementation is almost identical. If you just want the next shake, use Flow.first()
.Paul Woitaschek
01/19/2022, 5:52 AMlouiscad
01/19/2022, 8:35 AM