n

    nglauber

    1 year ago
    How can I get the same instance of my ViewModel across navigation? 🤔 I mean, I have a screen
    A
    which instantiate my ViewModel using
    viewModel()
    function. I want to get the same instance of my ViewModel in screen
    B
    after call
    navController.navigate("B")
    itnoles

    itnoles

    1 year ago
    nested graph?
    n

    nglauber

    1 year ago
    Not actually… ScreenA calls ScreenB
    i

    Ian Lake

    1 year ago
    If I'm understanding what you're saying, it sounds like this previous conversation: https://kotlinlang.slack.com/archives/CJLTWPH7S/p1621084875089500?thread_ts=1621077994.082300&cid=CJLTWPH7S
    n

    nglauber

    1 year ago
    Thanks @Ian Lake, but I don’t wanna use Hilt right now… Is there another way?
    i

    Ian Lake

    1 year ago
    The concept of using
    previousBackStackEntry
    applies to any kind of ViewModel
    I think the piece that we're missing is that there's no
    viewModel()
    method that takes a
    ViewModelStoreOwner
    (i.e., that
    previousBackStackEntry
    object)? It just always uses the
    LocalViewModelStoreOwner.current
    That sounds like a valid API we should add if you'd like to file an issue against AndroidX -> Lifecycle and include a link here
    viewModel()
    is just a one liner around
    ViewModelProvider(owner, factory).get()
    n

    nglauber

    1 year ago
    Great! I’ll do that… 👍 Definitely it’s better than pass the vm as “navigation param”
    i

    Ian Lake

    1 year ago
    Note that when your process is killed and recreated, you'll still be on screen
    B
    and that ViewModel won't exist anymore
    So your first access to it in screen B will be to create a brand new instance
    n

    nglauber

    1 year ago
    That’s important… Using Hilt will avoid that?
    i

    Ian Lake

    1 year ago
    Which is why the guide for returning a result uses the
    SavedStateHandle
    of the previous destination (which only contains information that survives process death and recreation): https://developer.android.com/guide/navigation/navigation-programmatic#returning_a_result
    No, all ViewModels get destroyed when you go through process death and recreation
    Just something to be aware of if you're assuming some data / state exists from Screen
    A
    . Of course, your own custom ViewModel could have its own
    SavedStateHandle
    - that same
    SavedStateHandle
    will be redelivered to the new instance upon recreation
    The Saved State integration with ViewModel docs talk about that general pattern: https://developer.android.com/topic/libraries/architecture/viewmodel-savedstate
    n

    nglauber

    1 year ago
    I see… but I guess this is different problem… If I implement the
    SavedStateHandle
    correctly in my ViewModel both screen will restore the data correctly, right?
    If I understand correctly, currently, to share a view model across navigation, I should use
    previousBackStackEntry
    . Lifecycle API nor Hilt can solve this right now…
    i

    Ian Lake

    1 year ago
    If all of the state you need in the ViewModel associated with Screen
    A
    can be saved into a
    SavedStateHandle
    it owns, then yep, it'll be restored properly whether it gets created from Screen
    B
    or Screen
    A
    The 'Don't keep activities' developer option is really handy for testing this case - it means that you can simulate process death just by hitting the home button, then relaunching your app from recents
    n

    nglauber

    1 year ago
    how can I pass the ViewModel to the
    previousBackStackEntry
    ? It’s a
    Bundle
    🤔
    i

    Ian Lake

    1 year ago
    So if on screen
    A
    , you did
    val vm: MyViewModel = viewModel()
    , screen
    B
    could do
    val vm: MyViewModel = ViewModelProvider(navController.previousBackStackEntry).get()
    to get that same ViewModel instance
    n

    nglauber

    1 year ago
    It’s not working… 😕 Is this what you asked me to open an issue?
    i

    Ian Lake

    1 year ago
    What 'isn't working'
    n

    nglauber

    1 year ago
    ViewModelProvider
    expects a
    ViewModelStoreOwner
    not a
    NavBackstackEntry
    😕
    i

    Ian Lake

    1 year ago
    NavBackStackEntry
    implements
    ViewModelStoreOwner
    n

    nglauber

    1 year ago
    You’re right… but it’s not working… let me check…
    i

    Ian Lake

    1 year ago
    Looks like you're missing a
    !!
    - the nullability is the problem, not the class
    n

    nglauber

    1 year ago
    It works! thanks @Ian Lake I’ll open the issue and post the link here 😉
    here it is: 😉 https://issuetracker.google.com/issues/188693123 not sure if it’s clear enough though…
    i

    Ian Lake

    1 year ago
    Close enough for me to work with it 🙂
    I suspect it would end up to be something like
    val vm: MyViewModel = viewModel(navController.previousBackStackEntry!!)
    n

    nglauber

    1 year ago
    Maybe some
    key
    param, or
    sharedViewModel()
    , or some scope…
    i

    Ian Lake

    1 year ago
    You have a scope - that's what a
    ViewModelStoreOwner
    is
    n

    nglauber

    1 year ago
    ok… I’d guess that would be nice to have
    viewModel<T>()
    will create a new instance and
    sharedViewModel<T>()
    will check if there’s an instance of the ViewModel, return it.
    i

    Ian Lake

    1 year ago
    Well,
    viewModel()
    already avoids creating a new ViewModel if the
    LocalViewModelStoreOwner
    has already created that ViewModel - it just returns the previously existing instance
    And outside of the
    LocalViewModelStoreOwner
    , there's many, many possible owners that might be appropriate