Status Update
Comments
il...@google.com <il...@google.com>
jb...@google.com <jb...@google.com>
an...@google.com <an...@google.com> #2
It is expected and not really related to navigation or NavBackStackEntry. It will work the same if you use `onActive` which is expected to be executed once when the composable became visible.
So how it works: when you display some screen the composable corresponding to this screen is being added into the composition. onActive/onCommit lifecycle callbacks are executed for it. when you switch to another screen we detach the no-longer-visible screen. onDispose callbacks are executed for the given composable. when later you open this screen again the corresponding composables are attached to the composition again and the new lifecycle events are triggered. the only state which survives the screen reopening is the one defined with rememberSavedInstanceState/savedInstanceState, everything else behaves as if it is a completely new screen
js...@gmail.com <js...@gmail.com> #3
Alright, thank you! Maybe this part of the documentation could be changed, then: The onCommit effect is a lifecycle effect that will execute callback every time the inputs to the effect have changed.
Is there a way to launch an effect that only runs once, then? What I am trying to achieve is get a callback for onDestroy of the navEntry's lifecycle, and currently my code subscribes several times to that lifecycle instead of once.
an...@google.com <an...@google.com> #4
js...@gmail.com <js...@gmail.com> #5
Oh well, what I am trying to do is precisely substituting the android ViewModel for a platform independent one.
I think there should be an option to opt out of using ViewModels, as they might not always make sense (when orientation change is disabled or when config changes are manually handled without recreating the activity).
an...@google.com <an...@google.com> #6
rememberSavedInstanceState {
println("will be executed once")
true
}
this will be executed only once
js...@gmail.com <js...@gmail.com> #7
Thank you! After your first answer I thought about trying this and it works.
It is hacky though, as you said. It would be better having a better option at some point :) should I create a feature request, instead, for this?
an...@google.com <an...@google.com> #8
js...@gmail.com <js...@gmail.com> #9
Since what I am trying to achieve is precisely substitute android viewModels, what I do is add a subscriber to the navEntry.lifecycle
and call the onCleared equivalent in the on destroy event. It works for me but I have not tested it thoroughly. Is there a reason why this should not work under some circumstances?
Since with compose it is quite easy to handle config changes manually, if you decide to go that road it makes no sense having an android viewModel, as it is designed precisely to survive config changes. For that reason I think it would make sense that the navigation component offered an alternative to using viewmodels (either through an alternative class or, even better, allowing us to use anything). That would be more lightweight and maybe not need to be built by the system through a factory.
an...@google.com <an...@google.com> #10
I think the approach with lifecycle could work
Description
Component used: Navigation
Version used: nav_compose_version = "1.0.0-alpha01", compose_version = '1.0.0-alpha06'
Devices/Android versions reproduced on: OnePlus 5T, Android 9
Steps to reproduce:
I open the app and press second screen on the bottom navigation bar. On commit is triggered with
androidx.navigation.NavBackStackEntry@931d32a
.I press the button to go to the third screen, and then I press system back. OnCommit is triggered again with
androidx.navigation.NavBackStackEntry@931d32a
.So the navigation component returns the same instance of NavBackStackEntry, but onCommit is triggered twice instead of once.