为什么必须删除作为 observeForever 添加到 LiveData 的观察者?

Why Observers added as observeForever to LiveData must be removed?

我在 Android LiveData documentation 上读到:

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.

我正在构建一个使用 MVVM 架构模式的应用程序 ViewModel 并在我的 ViewModel class 中声明 LiveDatas。在我的 viewModel 中,我将 observeForever 设置为 LiveData:

val password by lazy {
    MutableLiveData<String>()
}

init {
    initObservable()
}

private fun initObservable() {
    password.observeForever {
        ...
    }
}

根据我从文档中了解到的情况,每次实例化 ViewModel(使用之前的代码)的视图被销毁时,我都应该删除观察者,对吗?但是,一旦视图被销毁,观察者不应该被销毁吗(因为 ViewModel 实例在视图中被实例化并且也会被销毁)?

From what I understood from the documentation, I should remove the observer everytime the view that instantiates the ViewModel

要实现这一点,您应该在视图(Activity、片段)中实例化您的视图模型并像这样观察实时数据

val model = ViewModelProviders.of(this).get(MyViewModel::class.java)
        model.getUsers().observe(this, Observer<List<User>>{ users ->
            // update UI
        })

通过传递 this 将观察实时数据绑定到 view's 生命周期,因此当视图(Activity、片段)被销毁时,视图模型和观察者都将被销毁。

"I should remove the observer everytime the view that instantiates the ViewModel (with the previous code) was destroyed, right?"

如果您使用 observeForever(observer):

ViewModel 中观察 LiveData
  • 你不必担心View的生命周期,因为它不同于ViewModel的生命周期。 ViewModel 应该能够比创建它的 View 长寿。相反,框架将在不需要 ViewModel 时调用 onCleared(),因此您应该在此处处理移除观察者的问题。

如果您使用 observe(lifecyclerowner, observer)

View 中观察 LiveData
  • 当 lifecycleowner 被销毁时,观察者将被框架自动删除。


"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)?"

这个问题比 Android 更像是一个 Java 问题。

想想"being destroyed"是什么意思。 Android Framework 销毁 View 或 ViewModel 时,并不意味着该对象已从内存中完全删除。只要有其他对象(例如 observer)引用了它们,您的活动和片段就不会被垃圾回收。

如果你调用observe(activity, observer),那么Android框架可以跟踪activity实例和observer实例之间的连接,因此它可以杀死observer当它要杀activity的时候。但是,如果您只是简单地调用 observeForever(observer),Android Framework 根本无法判断该观察者属于哪个对象。

ViewModel 中实现 Sanlok Lee 的答案,它看起来像这样:

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()
}