Launching a coroutine from a Fragment using viewLifecycleOwner's lifecycleScope

Viewed 1109

I am launching coroutines from a Fragment, and I have the understanding that

lifecycleScope.launch {}

and

viewLifecycleOwner.lifecycleScope.launch {}

are basically the same thing in most circumstances.

Is there a benefit to using one over the other when launching a coroutine from inside a Fragment?

1 Answers

viewLifecycleOwner.lifecycleScope will only execute while the fragment's view is in the valid state. If you navigate away from the fragment, the coroutine still executing in that scope will be cancelled. While the coroutine launched in the lifecycleScope will complete.

You can try the following code to see for yourself. Assume this is launched from your fragment #1 in onViewCreated which automatically moves into fragment #2 in < 5 seconds.

val handler = CoroutineExceptionHandler {_, exception ->
            println("got $exception")
        }
        this.lifecycleScope.launch (handler) {
            try {
                println("LSCOPE: LifecycleOwner.lifecycleScope started")
                delay(5000)
                println("LSCOPE: LifecycleOwner.lifecycleScope completed")
            }
            catch(e: CancellationException){
                println("LSCOPE: lifecycleScope cancelled: $e")
            }
        }

        this.viewLifecycleOwner.lifecycleScope.launch (handler) {
            try {
                println("LSCOPE: viewLifecycleOwner.lifecycleScope started")
                delay(5000)
                println("LSCOPE: viewLifecycleOwner.lifecycleScope completed")
            }
            catch(e: CancellationException){
                println("LSCOPE: viewLifecycleOwner.lifecycleScope cancelled: $e")
            }
        }

while lifeCyclescope will complete successfully, the coroutine launched in viewLifecycleOwner.lifecycleScope will be cancelled;

I/System.out: LSCOPE: viewLifecycleOwner.lifecycleScope cancelled: kotlinx.coroutines.JobCancellationException: Job was cancelled; job=SupervisorJobImpl{Cancelling}@ed6f718

vs:

I/System.out: LSCOPE: LifecycleOwner.lifecycleScope completed

So, what benefit? In the eyes of the beholder - depends on your use case :)

Related