LiveData 记录
LiveData是一个可被观察的数据持有者类。与常规的Observable不同,LiveData能意识到应用程序组件的生命周期变化,这意味着它能遵守Activity、Fragment、Service等组件的生命周期。这种意识确保LiveData只更新处于活跃状态的应用程序组件Observer。
创建livedata对象:
val gatewayClick = MutableLiveData<GateWayBean>()
activity中观察livedata对象:
mViewModel.gatewayClick.observe(this, Observer {
if (SPConstants.getPwd(it.data!!.sn).isNotEmpty()){
mViewModel.sendLogin(it.data!!.ip,SPConstants.getPwd(it.data!!.sn))
}else{
showInputDialog(it)
}
})
更新livedata对象的值,有setvalue和postvalue两个方法
set:
gatewayClick.value = bean
此方法运行在主线程
post:
gatewayClick.postValue(bean)
此方法不指定线程,最后会调用setvalue方法,回调到主线程(可以在子线程直接调用)
记录:当在一个线程中很快的多次调用post方法时,会造成数据丢失
查看源码:
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
mPostValueRunnable:
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
猜测:再livedata将mPendingData的值再次设置为NOT_SET之前,再次调用post方法,会return调
通过在setvalue和postvalue方法中打印log,发现缺少set调用
解决方法:
自定义livedata,添加一个列表用于存储发送过来的消息值
val msgList = arrayListOf<T?>()
再post中将value加入msgList中
synchronized(msgList){
if (!msgList.contains(value)){
msgList.add(value)
if (msgList.size == 1){
super.postValue(msgList[0])
}
}
}
再set中移除
synchronized(msgList){
if (msgList.isNotEmpty()){
msgList.removeAt(0)
if (msgList.size > 0){
super.postValue(msgList[0])
}
}
}
注意:在set方法中不需要将value加入msgList中