Michael Ferguson
1 min readMar 15, 2021

--

Hi, great question. I did cover this in the article lightly but it’s easy to miss.

The issues with using the launchWhenX functions are related to cancellation not when you call it nor is it related to receiving multiple events. All of them cancel when the lifecycle reaches the destroyed state. launchWhenStarted, however, pauses after onStop before it cancels fully after onDestroy. (launchWhenResumed has a similar issue, but it just pauses earlier.) This makes it possible to receive an events / side effect after onStop has been reached. This is bad for cases like navigation events which should only be performed between onStart and onStop.

It doesn't matter when you register the launchWhenX lambda. You could register it in onCreate if you wanted or even in onResume, dealing with the repeated registration of course. The pausing of the dispatcher onStop followed by the cancellation in onDestroy is the problem.

I’d recommend you check out https://medium.com/swlh/deep-dive-into-lifecycle-coroutines-e7192312faf which describes the underlying mechanisms in the launchWhenX functions.

You can see a simplified demonstration of events getting dropped here: https://gist.github.com/fergusonm/88a728eb543c7f6727a7cc473671befc

I’ve added some notes to the bottom of the gist that explain the issue. The TLDR though is that launchWhenStarted pauses onStop but doesn’t cancel until onDestroy, leading to event loss and potential receipt of an even when it’s not safe to observe it.

--

--

Michael Ferguson
Michael Ferguson

Written by Michael Ferguson

Android software developer. Views and opinions expressed are my own and not that of my employer.

No responses yet