问题描述
dialog里监听了liveData数据变化,当dialog打开关闭再次打开时候,会发现旧数据会再次灌入。等到网络请求回来,新数据才会展示。
现象
页面首先展示老数据,过一会又展示新的数据。又称为数据倒灌。
解决方案
- 使用LiveEvent替换原来的MutableLiveData,解决
val liveData = LiveEvent<Model?>()
/**
* @desc fix 粘性事件引发的问题
*/
open class LiveEvent<T> : MediatorLiveData<T>() {
private val observers = ArraySet<ObserverWrapper<in T>>()
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
observers.find { it.observer === observer }?.let { _ -> // existing
return
}
val wrapper = ObserverWrapper(observer)
observers.add(wrapper)
super.observe(owner, wrapper)
}
@MainThread
override fun observeForever(observer: Observer<in T>) {
observers.find { it.observer === observer }?.let { _ -> // existing
return
}
val wrapper = ObserverWrapper(observer)
observers.add(wrapper)
super.observeForever(wrapper)
}
@MainThread
override fun removeObserver(observer: Observer<in T>) {
if (observer is ObserverWrapper && observers.remove(observer)) {
super.removeObserver(observer)
return
}
val iterator = observers.iterator()
while (iterator.hasNext()) {
val wrapper = iterator.next()
if (wrapper.observer == observer) {
iterator.remove()
super.removeObserver(wrapper)
break
}
}
}
@MainThread
override fun setValue(t: T?) {
observers.forEach { it.newValue() }
super.setValue(t)
}
private class ObserverWrapper<T>(val observer: Observer<T>) : Observer<T> {
private var pending = false
override fun onChanged(t: T?) {
if (pending) {
pending = false
observer.onChanged(t)
}
}
fun newValue() {
pending = true
}
}
}
- 使用SharedFlow
参考文章
Jetpack MVVM 中正确处理 Events 链接