Hey, I just started with compose and I have someth...
# compose
w
Hey, I just started with compose and I have something like
@Composable
fun A() { }
@Composable
fun B() {}
I start in A, then I navController.navigate() to B. Then, I go back by pressing the back button and A is recreated from scratch, as the LifecycleEventObservers passes the on_create, on_start and on_resume, like this: A: ON_CREATE A: ON_START A: ON_RESUME navigating to B B: ON_CREATE B: ON_START B: ON_RESUME back button A: ON_CREATE A: ON_START A: ON_RESUME Is there something wrong in my code, or is this the expected behaviour? I don't want A to be recreated every time I go back to it
i
It isn't being recreated at all - what you're seeing is just a consequence of how LifecycleObservers work - they always "catch you up" to the current state by sending a brand new observer every upward event (that way when you get downward events the upward events were sure to have run)
And since you're adding a new LifecycleObserver each time you go to that screen, you always get that catch up behavior.
This is something we're hoping to take into consideration for you in https://issuetracker.google.com/issues/235529345
But it is a bit tricky because even on that first composition, your Lifecycle has already reached STARTED by the time the composition first occurs so you can't, in pure Compose code, tell the difference between that and coming back to the same destination (where you'll also already be STARTED)
w
oh, ok! thanks for the explanation.. so I wonder how I can understand if I'm starting it or coming back, since I need to call a method only one time. I tried using a LaunchedEffect, but it's also called when I go back
Like this it works but it feels like a hack:
Copy code
var initialized by rememberSaveable {
    mutableStateOf(false)
}
if(!initialized) {
    initialized = true
    doSomethingOnce()
}
r
For example:
Copy code
LaunchedEffect(backStackEntry) {

}
NavBackStackEntry
is what gets passed to you in the
composable { }
calls you do in the NavHost.
you can pass that to the Composable screen function if you want, and then pass it into LaunchedEffect as a key, ensuring that this happens only once for a given
NavBackStackEntry
. Which seems like it's what you want.
w
I tried with LaunchedEffect(Unit) { } and LaunchedEffect(mySameParameter) { } and it was also launched on back pressed
r
hmm. well, usually I do this sort of code in the constructor (
init {}
) of the ViewModel.
w
I don't have a viewmodel 🙂 I use reduxkotlin so I need to dispatch the initialization action when the section opens
it's more of an edge-case, because in all sections but one it's not a problem to dispatch the action again
r
when going back, for all "Compose intents and purposes", it's a new screen. The only difference is when you use compose navigation you have a NavBackStackEntry which survives and knows which Composable to call for you
so if your logic is tied to NavBackStackEntry, you should use that directly, somehow
w
understood, I'll dig into it, thanks!