我的视图模型中有一个MutableLiveData
:
val liveData = MutableLiveData<ArrayList<*>>()
我将来自端点调用的结果添加到此LiveData
,如下所示:
liveData.value?.addAll(myList)
据我所知,MutableLiveData
不应通知它是Observer
,除非您对它执行setValue
或postValue
,但此时我的代码是运行,Observer
会收到更改通知。
这怎么可能?
我遇到了一个更加奇怪的行为,该测试通过了,但是列表一次被打印出来:[]
@Test
fun `strange live data behavior`() {
val myLiveData = MutableLiveData<ArrayList<Int>>()
val observer = mock() as Observer<ArrayList<Int>>
myLiveData.observeForever(observer)
myLiveData.observeForever { println(it) }
myLiveData.value = ArrayList()
verify(observer).onChanged(ArrayList())
myLiveData.value?.addAll(listOf(1, 2, 3, 4))
val result = ArrayList<Int>()
result.add(1)
result.add(2)
result.add(3)
result.add(4)
verify(observer).onChanged(result)
}
答案 0 :(得分:2)
当LiveData
发送通知时,LiveData
不会发送该项目的副本。取而代之的是,它只是传递对持有的同一实例的引用。
这意味着如果您像这样修改LiveData
内部的数据:
myLiveData.value?.addAll(listOf(1, 2, 3, 4))
观察者先前收到的ArrayList
对象也将被修改而不会被调用Observer.onChanged()
,仅仅是因为它们是同一对象。这就是为什么在LiveData
或任何观察者/反应模式中使用可变对象通常不是一个好主意的原因。
要验证onChanged()
实际上仅被调用一次,请在测试结束时添加以下行:
@Test
fun `strange live data behavior`() {
val myLiveData = MutableLiveData<ArrayList<Int>>()
val observer = mock() as Observer<ArrayList<Int>>
myLiveData.observeForever(observer)
myLiveData.observeForever { println(it) }
myLiveData.value = ArrayList()
verify(observer).onChanged(ArrayList())
myLiveData.value?.addAll(listOf(1, 2, 3, 4))
val result = ArrayList<Int>()
result.add(1)
result.add(2)
result.add(3)
result.add(4)
verify(observer).onChanged(result)
// Below should pass because onChanged is only called once.
verify(observer, times(1)).onChanged(any())
}