streetsofboston
12/05/2018, 2:39 PMJob
forever - the only way to complete the Job
would be through cancellation of its scope.
I used the delay(Long.MAX_VALUE)
to accomplish this, but this seems wrong.
Basically, the function below returns a channel that keeps sending location-updates until its enclosing scope gets cancelled.
override fun CoroutineScope.publishLocations(): ReceiveChannel<Pair<Double, Double>> =
Channel<Pair<Double, Double>>(capacity = Channel.CONFLATED).apply {
val locationListener = locationListener {
launch { send(it.latitude to it.longitude) }
}
launch {
// locationListener keeps being called each time the phone's
// location changes, and the locations are sent to `this` Channel over and over again.
locationManager.requestLocationUpdates(5_000L, 0f, CRITERIA, locationListener, null)
delay(Long.MAX_VALUE) // suspend forever ...
}.invokeOnCompletion {
// .. until the Job (its outer CoroutineScope) is cancelled.
// Close this Channel
close(it)
// And stop the locationManager from sending additional updates.
locationManager.removeUpdates(locationListener)
}
}
Is there a better alternative to creating a Job
that suspends forever until it’s cancelled?plastiv
12/05/2018, 3:33 PMstreetsofboston
12/05/2018, 3:40 PMChannel
until the Job
is cancelled.
My example works, but i’m wondering if this is the correct way of doing this.
Using a suspendCoroutine
, using the Continuation
it provides, is only for a callback that happens once, not one that gets called over and over again.delay
):
suspend fun suspendForever(): Nothing = suspendCancellableCoroutine<Nothing> { /* Do nothing, never resume */ }
Dico
12/06/2018, 12:34 AMchannel.offer
instead of channel.send
, which is not a suspending function so you don't need to wrap it in a coroutine.streetsofboston
12/06/2018, 1:41 AMoffer
method.
Using a coroutine (launching it within a Scope) is the most convenient way, that I found, to be able to handle a Scope-cancellation (e.g. the Activity/Fragment is destroyed) while the Job is handling callbacks from the GPS, as long as the Job is not cancelled.
I don’t know another way of keeping the Job alive while callbacks from the GPS keep coming in; this seems easiest by just suspending indefinitely the Job until it is cancelled (by the enclosing Scope) or by an exception.
But I agree… using a looooooong delay or a suspendForever
smells a bit off 🙂Jonathan
12/06/2018, 9:33 AMstreetsofboston
12/06/2018, 11:53 AM