Why a new instance of ViewModel is created after navigation back?

Viewed 492

I'm currently developing an Android application based on MVVM, so I'm using the ViewModel principle to contain my UI data.

I also know that a ViewModel is linked to its owner and that it was destroyed when the owner is destroyed. (https://developer.android.com/topic/libraries/architecture/viewmodel).

enter image description here

My problem occurs between Fragment A and B (visible on the image above).

My Fragment A contains a recyclerview which, when I click on the element, directs me to Fragment B using the component navigation (see example below).

view?.findNavController()?.navigate(R.id.action_commandListFragment_to_commandDetailsFragment)

My fragment B initializes the "CommandDetailViewModel" using the ViewModelProvider and its sub fragment (C & D) retrieves it by passing "requireParentFragment()" as argument of the ViewModelProvider.

//Fragment B
mviewModel = ViewModelProvider(this).get(CommandDetailsViewModel::class.java)


//Fragment C & D
mparentViewModel = ViewModelProvider(requireParentFragment()).get(CommandDetailsViewModel::class.java)

If I click on a button on fragment D, I go back to fragment A, always using the controller navigation.

//In Fragment B
mviewModel.mCurrentCommandFinished.observe(viewLifecycleOwner, Observer {
        if(it){
            view?.findNavController()?.navigate(R.id.action_commandDetailsFragment_to_commandListFragment)
        }
    })

So far I understand, but I realized that I was doing something wrong, indeed, this return to fragment A does this because a boolean LiveData of the ViewModel changes to "true" and is therefore left to "true", even after navigation.

I was expecting to have a problem when I click on Item 1, the variable being as true I would have been immediately put back on my list but it is not the case, a new ViewModel is created so the value is set to false (default one) and I don't understand why.

Does the navigation have the effect of completely destroying fragment B and thus the associated viewModel ?

Because I don't understand why a new instance of the viewModel is created each time I click on my element while my child fragments manage to get the previously created instance.

NB: The viewModel affection are done in "onActivityCreated(savedInstanceState: Bundle?)" in fragment B, C & D.

EDIT : I tried to put a log in the override "onDestroy()" function of Fragment B and I discover that the fragment wasn't destroy & his VM neither.

The problem is that I recreated a new instance of my fragment with

view?.findNavController()?.navigate(R.id.action_commandListFragment_to_commandDetailsFragment)

Is there a way to retrieve the "original" instance or destroyed it ?

EDIT 2 : It was my fault, I don't exploit the "popUpTo" & "popUpToInclusive" variables on the action from Fragment B to Fragment A, so my fragment B was still in stack but not used anymore, now it's destroyed properly (https://developer.android.com/guide/navigation/navigation-navigate)

0 Answers
Related