Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared ViewModel's onCleared() is never called

I have a single Activity application. In one part of the app there is a master-detail combination of Fragments that use a shared ViewModel to share some data between them. The problem I face is that the ViewModel's onCleared() method is not called even when both of the Fragments have been destroyed. onCleared() is only called when the activity is destroyed.

Is this how it is supposed to work? Because that is quite useless in a single Activity model, because the Activity is always alive. Or am I missing something?

like image 616
rozina Avatar asked Feb 21 '19 07:02

rozina


People also ask

What is onCleared in ViewModel?

onCleared. This method will be called when this ViewModel is no longer used and will be destroyed. It is useful when ViewModel observes some data and you need to clear this subscription to prevent a leak of this ViewModel.

What is Sharedviewmodel?

In android, we can use ViewModel to share data between various fragments or activities by sharing the same ViewModel among all the fragments and they can access everything defined in the ViewModel. This is one way to have communication between fragments or activities.

Why does ViewModel survive configuration changes?

ViewModel is a separate class which has an instance of it in the activity and has no reference for view in it. So even though activity onDestroy() and onCreate() happens on configuration change, the instance of ViewModel doesn't get destroyed or garbage collected.

What happens when a view model is destroyed?

Fantastic libraries and article! You are correct: the ViewModel is destroyed if your process is killed by Android. Just like before, you should use onSaveInstanceState() to store any data you must have to later recreate your Activity in the same state as before.


1 Answers

It would be a little hard to give a solid answer without seeing a little bit of code. My first guess would be that you might have scoped the ViewModel to your Activity and not the Fragment's themselves.

//inside of fragment onCreate()

//scoped to fragment
viewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)

//scoped to activity
viewModel = ViewModelProviders.of(requireActivity()).get(SharedViewModel::class.java)

If this is the case, if you look at the diagram for the scope of a ViewModel. Then the reason why onCleared() never gets called is because your Activity has never technically gotten destroyed since it is what keeps your app on the foreground.

enter image description here

If this isn't the right solution to your problem, then I think the docs on ViewModel might be a good place to start looking for the right answer. Happy coding!

like image 102
Andrew Steinmetz Avatar answered Sep 19 '22 18:09

Andrew Steinmetz