I'm becoming crazy.
I have a SharedViewModel shared between FragmentA and FragmentB, which contains a LiveData:
class SharedViewModel : ViewModel() {
private val _searchParameters = MutableLiveData(SearchParameters())
val searchParameters: LiveData<SearchParameters> = _searchParameters
}
and I observe this liveData in the onViewCreated() of my FragmentA (only, not in FragmentB):
viewModel.searchParameters.observe(viewLifecycleOwner) { searchAndFilter ->
Log.d("FragmentA", "observed searchParameters in FragmentA")
mSearchAdapter.updateSearchParameters(searchAndFilter)
}
My problem is that the observer never gets removed when FragmentA is destroyed:
If I navigate to FragmentB (using Navigation Component), then from FragmentB I do findNavController().popBackStack(), I would expect FragmentA to have removed my observer in onDestroyView() (which I have confirmed is called correctly when navigating to FragmentB). But this isn't happening. So when I navigate back to FragmentA, the LiveData is being observed another time, and now I have multiple observations of this LiveData. If I navigate back and forth 10 times, my observer has now been registered 10 times and is being called 10 times foe every event.
I have also tried removing the observer manually by keeping a reference to it and doing
override fun onDestroyView() {
super.onDestroyView()
Log.d("FragmentA", "onDestroyView")
viewModel.searchParameters.removeObserver(searchParametersObserver)
}
But the same problem occurs.
So my question is what is going on, and how can I fix this problem?
I created a sample test project at Github link that goes from
fragmentAtoFragmentB. It seems to work correctly, when onFragmentB,FragmentAstops receiving events and when back toFragmentA,FragmentBstops receiving events. AndFragmentAis always reused whilefragmentBis recreated (seehashCodes)I think your problem could be caused by something else such as: wrong sharedViewModel config, incorrect navigation configuration on
navigation.xmlor incorrect navigation from A to B. I suggest checking the sample link and see if what you're doing matches it.