androidandroid-jetpack-composenavhostcontroller

How can DisposableEffect with LocalLifecycleOwner help observe the lifecycle of a Composable?


I'm working with Jetpack Compose, and I need to observe the lifecycle of a Composable, but I'm a bit confused about how it works. From what I understand, LocalLifecycleOwner is bound to the lifecycle of the Activity or Fragment that contains the Composable. However, I'm wondering how I can use DisposableEffect with LocalLifecycleOwner to observe the lifecycle of the current Composable itself.

Here is my code:

DisposableEffect(lifecycleOwner) {
    val observer = LifecycleEventObserver { _, event ->
        when (event) {
            Lifecycle.Event.ON_RESUME -> {
                lifecycle = true
            }
            Lifecycle.Event.ON_PAUSE -> {
                lifecycle = false
            }
            else -> {}
        }
    }

    lifecycleOwner.lifecycle.addObserver(observer)

    onDispose {
        lifecycleOwner.lifecycle.removeObserver(observer)
    }
}

Given that LocalLifecycleOwner is tied to the Activity or Fragment's lifecycle, how can this approach correctly observe the lifecycle of the current Composable? Shouldn't the lifecycle of a Composable be separate from its Activity or Fragment? What is the internal mechanism behind this behavior?

When I use NavHost to navigate away from the current Composable to another Composable, the above code is able to detect the lifecycle state changes of the current Composable, such as triggering ON_PAUSE or ON_RESUME events. This confuses me because LocalLifecycleOwner is generally tied to the lifecycle of the Activity or Fragment, not the specific Composable. Why is it that by using DisposableEffect and LocalLifecycleOwner to observe lifecycle events, it can effectively detect the state changes of the current Composable? What is the mechanism behind this behavior?


Solution

  • Given that LocalLifecycleOwner is tied to the Activity or Fragment's lifecycle, how can this approach correctly observe the lifecycle of the current Composable?

    Composables do not have a Lifecycle - a LifecycleOwner has a Lifecycle. A ComponentActivity and Fragment are just two of many subclasses of LifecycleOwner.

    When I use NavHost to navigate away from the current Composable to another Composable, the above code is able to detect the lifecycle state changes of the current Composable, such as triggering ON_PAUSE or ON_RESUME events. This confuses me because LocalLifecycleOwner is generally tied to the lifecycle of the Activity or Fragment, not the specific Composable.

    One of the other subclasses of LifecycleOwner is NavBackStackEntry - the exact class that is created for each screen the NavController has on its back stack. NavHost automatically ensures that the LocalLifecycleOwner within a given screen is set to that screen's NavBackStackEntry which is why you see the behavior you see.

    The lifecycle-runtime-compose library contains a number of built-in APIs for using Lifecycle in Compose, which means you should never have to directly use DisposableEffect.

    Instead, the code you've posted could use LifecycleResumeEffect:

    LifecycleResumeEffect {
      lifecycle = true
    
      onPauseOrDispose {
        lifecycle = false
      }
    }