Reputation: 9467
I've read on Android LiveData documentation that:
You can register an observer without an associated LifecycleOwner object using the observeForever(Observer) method. In this case, the observer is considered to be always active and is therefore always notified about modifications. You can remove these observers calling the removeObserver(Observer) method.
I'm building an app using MVVM architecture pattern using ViewModel and declaring LiveDatas inside my ViewModel class. At my viewModel I have set a observeForever
to a LiveData:
val password by lazy {
MutableLiveData<String>()
}
init {
initObservable()
}
private fun initObservable() {
password.observeForever {
...
}
}
From what I understood from the documentation, I should remove the observer everytime the view that instantiates the ViewModel (with the previous code) was destroyed, right? But shouldn't the Observers be destroyed once the view is destroyed (since the ViewModel instance was instantiated in the view and will also be destroyed)?
Upvotes: 16
Views: 15590
Reputation: 826
Implementing Sanlok Lee's answer in a ViewModel, it would look like this:
val password by lazy {
MutableLiveData<String>()
}
private val passwordObserver = Observer<String> {
...
}
init {
initObservable()
}
private fun initObservable() {
password.observeForever(passwordObserver)
}
override fun onCleared() {
password.removeObserver(passwordObserver)
super.onCleared()
}
Upvotes: 4
Reputation: 3494
"I should remove the observer everytime the view that instantiates the ViewModel (with the previous code) was destroyed, right?"
If you are obsering a LiveData
in ViewModel using observeForever(observer)
:
onCleared()
when the ViewModel is not needed, so that's where you should handle removing the observer.If you are observing a LiveData
in View using observe(lifecyclerowner, observer)
"But shouldn't the Observers be destroyed once the view is destroyed (since the ViewModel instance was instantiated in the view and will also be destroyed)?"
This question is more of a Java question than Android.
Think about what it means by "being destroyed". When a View or ViewModel is destroyed by the Android Framework, it does not mean that the object is completely removed from the memory. Your activities and fragments will not be garbage collected as long as there are other objects (such as observer) that has reference to them.
If you call observe(activity, observer)
, then the Android Framework can track the connection between the activity
instance and the observer
instance, and therefore it can kill observer
when it wants to kill activity
. However if you simply call observeForever(observer)
there is simply no way for Android Framework to tell which object this observer belongs to.
Upvotes: 26
Reputation: 9615
From what I understood from the documentation, I should remove the observer everytime the view that instantiates the ViewModel
To achieve this you should instantiate your viewmodel inside the View (Activity, Fragment) and observe the livedata like this
val model = ViewModelProviders.of(this).get(MyViewModel::class.java)
model.getUsers().observe(this, Observer<List<User>>{ users ->
// update UI
})
by passing this
you tie observing livedata to view's
lifecycle, so when View (Activity, Fragment) will be destroyed both viewmodel and observer will be destroyed.
Upvotes: 1