Handling Android lifecycle events with Coroutines


#1

Consider the following example:

var job: Job? = null

fun foo() {
  job = launch(UI) {
    val bar = download().await()
    // Cancel could have been called now
    // The following code is posted to the Handler
    performSomeWorkOnTheUI(bar)
  }
}

override fun onPause() {
  job?.cancel()
}

Cancelling the job in onPause will make await throw, but when it is cancelled after await has returned, things will go wrong. Since performSomeWorkOnTheUi(bar) is posted as a Runnable to a Handler associated with the main thread, the UI may be already paused and thus unavailable when the function is invoked.

The only way I found to avoid this issue was wrapping the call to performSomeWorkOnTheUI inside if (isActive). Since the check is posted to the Handler as well, it is running on the UI thread. I’m wondering if there’s a cleaner way to do this, since it’s easy to forget checking isActive after code has been posted to a Handler. Ideally, the coroutine library would check for me whether the job was cancelled after the continuation resumes on the UI thread, but of course before the code that follows the await() runs.


#2

I’ve answered in the corresponding issue for kotlinx.coroutines project: https://github.com/Kotlin/kotlinx.coroutines/issues/47