Когда 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())
}