Mohamed
02/11/2021, 4:10 PMwithTimeout
inside suspendCoroutine
? something like:
suspendCoroutine{ cont->
withTimeout(1000){
// DO something
cont.resumeWithException(Exception("Timeout"))
}
}
gildor
02/11/2021, 4:18 PMZach Klippenstein (he/him) [MOD]
02/11/2021, 4:41 PMMohamed
02/11/2021, 4:47 PMprivate suspend fun callSomeGooglePlayServicesApi(): List<String> = suspendCoroutine { cont ->
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
cont.resume(intent.getArrayList())
context.unregisterReceiver(this)
}
}
context.registerReceiver(receiver)
googleApiClient.someTask()
.addOnSuccessListener {
withTimeout(15000) {
context.unregisterReceiver(preAuthKeysReceiver)
cont.resumeWithException(Exception("Time out"))
}
}.addOnFailureListener {
cont.resumeWithException(it)
context.unregisterReceiver(receiver)
}
}
Zach Klippenstein (he/him) [MOD]
02/11/2021, 5:15 PMZach Klippenstein (he/him) [MOD]
02/11/2021, 5:16 PMsuspendCancellableCoroutine
include a simple code sample that demonstrates how to use it pretty well.Mohamed
02/11/2021, 5:21 PMMohamed
02/11/2021, 5:21 PMZach Klippenstein (he/him) [MOD]
02/11/2021, 5:23 PMwithTimeout
will already throw its own timeout exception. Your code is throwing your own exception when the google task completes successfully, but i don’t understand why you’d want that to look like a timeout to the caller.Zach Klippenstein (he/him) [MOD]
02/11/2021, 5:26 PMprivate suspend fun awaitReceivedBroadcast(): Intent =
suspendCancellableCoroutine { cont ->
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
context.unregisterReceiver(this)
cont.resume(intent)
}
}
context.registerReceiver(receiver)
cont.invokeOnCancellation {
context.unregisterReceiver(receiver)
}
}
}
Dominaezzz
02/11/2021, 5:26 PMfirst
in a withTimeout. Zach Klippenstein (he/him) [MOD]
02/11/2021, 5:26 PMZach Klippenstein (he/him) [MOD]
02/11/2021, 5:27 PMZach Klippenstein (he/him) [MOD]
02/11/2021, 5:29 PMprivate suspend fun callSomeGooglePlayServicesApi(): List<String> =
withTimeout(15_000) {
coroutineScope {
// Need to launch at least one of these calls into its own coroutine
// so they run concurrently.
val list = awaitReceivedBroadcast().getArrayList()
// …
val taskResult = googleApiClient.someTask().await()
// Do something with the result.
}
}
Dominaezzz
02/11/2021, 5:33 PMprivate suspend fun awaitReceivedBroadcast(): Intent =
callbackFlow<Intent> {
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
send(intent)
}
}
context.registerReceiver(receiver)
awaitClose { context.unregisterReceiver(receiver) }
}.first()
Zach Klippenstein (he/him) [MOD]
02/11/2021, 5:41 PMsend
from onReceive
since it’s a suspend function, you’d need sendBlocking
Dominaezzz
02/11/2021, 5:44 PMcont.resume
being called more than once. (Yeah should be `sendBlocking`/`offer` )gildor
02/12/2021, 6:13 AMuli
02/12/2021, 9:18 AMsuspend(Cancelable)Coroutine
. All further business logic like timeouts and so on are a lot easier then to do on top the suspend function