LiveData学习笔记-事件丢失

2022-07-13  本文已影响0人  紫鹰

LiveData一个具有生命周期感知能力的观察者模式,是在页面与数据分离中维持页面和数据的一致性的桥梁。

基本使用

一般在ViewModel中定义

val uiStatusLiveData = MutableLiveData<LoginUiStatus>()

在需要通知页面的数据变化的时候,将消息发布

val status = LoginUiStatus()  
status.needDismissDialog = true  
uiStatusLiveData.postValue(status)

在activity或者fragment中只要注册观察着就好了

viewModel.uiStatusLiveData.observe(this) { status ->  
   //更改UI的代码 

}  

以上就是简单的使用,然而在使用过程中出现了一个问题:发送数据丢失。

数据丢失问题

事情的起因是这样的,我在viewmodel中周期性的发一个消息去通知UI改变,在周期之外,还发了其他的消息。可是有时候却收不到周期之外的消息。于是去查源码看看问题出在了哪。

protected void postValue(T value) {  
    boolean postTask;  
    synchronized (mDataLock) {  
        postTask = mPendingData == NOT_SET;  
        mPendingData = value;  
    }  
    if (!postTask) {  
        return;  
    }  
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);  
}

这代码就有意思了,如果一次发送很多,LiveData来不及发送的话,他就会丢弃最早获取的而只发送最后一个消息。如果一次发送消息太多的时候,重要的中间态消息会被丢弃。

那么发送消息还有另一个方法即setValue()

@MainThread  
protected void setValue(T value) {  
  assertMainThread("setValue");  
  mVersion++;  
  mData = value;  
  dispatchingValue(null);  
}

这个方法不会丢失消息,但是只能在主线程中使用

总结

setValue方法,不会丢失消息,但是必须在主线程中使用

postValue方法,会丢失消息,可以在子线程中使用

下一篇,看一下LiveData的源码,看看从发送到接收,中间究竟经历了什么,看看他如何检测生命周期的。

上一篇下一篇

猜你喜欢

热点阅读