ViewModel
中的可变LiveData:
val viewStateLiveData: MutableLiveData<SomeViewState> = MutableLiveData()
当网络调用失败时,将从主线程中调用此函数(在ViewModel
中)以更新视图状态对象(以显示Snackbar,然后重置状态,这样就不会重新显示):
@UiThread
private fun onFailure() {
viewStateLiveData.value = viewStateLiveData.value?.copy(retrievalSuccess = false, showProgress = false)
viewStateLiveData.value = viewStateLiveData.value?.copy(retrievalSuccess = null)
}
该片段观察到MutableLiveData
:
viewModel.viewStateLiveData.observe(this, Observer { viewState ->
Timber.i("Update ViewState: $viewState")
})
但是输出是单个观察者调用(代表第二个突变):
Update ViewState: ViewState(retrievalSuccess=null, showProgress=false)
而不是我所期望的,这是对观察者的两次调用,反映了两种变异:
Update ViewState: ViewState(retrievalSuccess=false, showProgress=false)
Update ViewState: ViewState(retrievalSuccess=null, showProgress=false)
为什么MutableLiveData.setValue()
在两个突变之后都没有触发观察者?文档说:“设置值。如果有活动的观察者,该值将分派给他们。”但是很难断定并非如此,因为正在调用setValue(),但是没有触发观察器(处于活动状态)。观察者肯定是在MutableLiveData
突变之前建立的。
我尝试了一系列突变,但只看到一个观察者调用,该观察者接收到一个结合了所有先前突变的视图状态对象。因此,对setValue()
的调用改变了视图状态,但是只有系列中的最后一个调用才触发观察者。
我尝试徒然使用postValue()
。奇怪的是,我要描述的这种行为直到最近才出现,但尚不清楚是什么引起了这些问题。
答案 0 :(得分:0)
这是一个Fragment生命周期/定时问题,最终是由Fragment处于活动状态之前发生的ViewState突变引起的,因此,当Fragment到达Active时,LiveData只是收到一个事件,代表了直至在单个初始事件中就是这一点。
要解决此问题,请进行以下更改:
onCreate()
-创建ViewModel
onViewCreated()
-开始观察LiveData
onResume()
/ onStart()-发出网络请求(启动已突变视图状态流)
在调试此问题时,向其中添加日志记录以查看Fragment处于什么状态确实很有帮助:fragmentManager?.registerFragmentLifecycleCallbacks(...)