When querying an Android `ContentResolver` you can...
# coroutines
m
When querying an Android
ContentResolver
you can optionally pass a
CancellationSignal
argument. So I would like to call
cancel()
on that object when the coroutine is cancelled. Is there a way to do this without using
suspendCancellableCoroutine
(since I don’t need the whole
resume()
functionality)?
Copy code
suspendCancellableCoroutine<Result> { continuation ->
    val cancellationSignal = CancellationSignal()
	continuation.invokeOnCancellation { 
    	cancellationSignal.cancel()
	}
	val result: Result = resolver.query(args, cancellationSignal)
	continuation.resume(result)
}
o
coroutineContext[Job]!!.invokeOnCompletion
takes an argument to inform you of cancellation as well, could probably use that
👍 1
m
Thanks! I wonder about tidying up once the query has finished. Can it be cleared?
m
Ah, thanks I missed that
DisposableHandle
Copy code
suspend inline fun <T> usingCancellationSignal(action: (CancellationSignal) -> T): T {
    val cancellationSignal = CancellationSignal()
    val disposableHandle = coroutineContext[Job]!!.invokeOnCompletion { cause ->
        if (cause is CancellationException) {
            cancellationSignal.cancel()
        }
    }
    try {
        return action(cancellationSignal)
    } finally {
        disposableHandle.dispose()
    }
}
I added a check to make sure
CancellationSignal.cancel()
is only called when the cause is
CancellationException