优化livedata数据倒灌
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package com.ttstd.dialer.livedata;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* 解决一次性事件的数据倒灌问题,仅通知一次观察者
|
||||
*/
|
||||
public class SingleLiveEvent<T> extends MutableLiveData<T> {
|
||||
private static final String TAG = "SingleLiveEvent";
|
||||
private final AtomicBoolean mPending = new AtomicBoolean(false); // 标记事件是否待处理
|
||||
|
||||
@MainThread
|
||||
@Override
|
||||
public void observe(androidx.lifecycle.LifecycleOwner owner, final Observer<? super T> observer) {
|
||||
// 警告:多个观察者同时注册时,只有一个会收到通知
|
||||
if (hasActiveObservers()) {
|
||||
Log.w(TAG, "多个观察者注册,但仅第一个会收到事件");
|
||||
}
|
||||
|
||||
// 包装观察者,仅在事件未处理时触发
|
||||
super.observe(owner, t -> {
|
||||
if (mPending.compareAndSet(true, false)) { // 原子操作:如果是true则改为false,并返回true
|
||||
observer.onChanged(t); // 触发观察者回调
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@MainThread
|
||||
@Override
|
||||
public void setValue(T value) {
|
||||
mPending.set(true); // 标记事件待处理
|
||||
super.setValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 简化Void类型事件的调用(如无参数的事件)
|
||||
*/
|
||||
@MainThread
|
||||
public void call() {
|
||||
setValue(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.ttstd.dialer.livedata;
|
||||
|
||||
/**
|
||||
* 包装数据和版本号,用于版本校验
|
||||
*/
|
||||
public class VersionedData<T> {
|
||||
private final T data; // 实际数据
|
||||
private final int version; // 数据版本号
|
||||
|
||||
public VersionedData(T data, int version) {
|
||||
this.data = data;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.ttstd.dialer.livedata;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
|
||||
/**
|
||||
* 通过版本号控制数据消费,避免旧数据倒灌
|
||||
*/
|
||||
|
||||
/**
|
||||
* 带版本控制的LiveData,解决数据倒灌问题
|
||||
*/
|
||||
public class VersionedLiveData<T> extends LiveData<VersionedData<T>> {
|
||||
private int currentVersion; // 数据版本号(初始化为0)
|
||||
|
||||
// 修正:父类构造器直接使用初始版本0,避免引用未初始化的currentVersion
|
||||
public VersionedLiveData() {
|
||||
super(new VersionedData<>(null, 0)); // 初始数据版本为0
|
||||
this.currentVersion = 0; // 初始化版本号(与父类初始数据一致)
|
||||
}
|
||||
|
||||
/**
|
||||
* 修正:改名避免与父类setValue冲突(父类setValue参数为VersionedData<T>)
|
||||
* 更新数据并自动递增版本号
|
||||
*/
|
||||
@MainThread
|
||||
public void setNewValue(T newValue) {
|
||||
currentVersion++; // 版本号递增
|
||||
// 调用父类的setValue,传入包装后的带版本数据
|
||||
super.setValue(new VersionedData<>(newValue, currentVersion));
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册带版本校验的观察者,仅接收新版本数据
|
||||
*/
|
||||
public void observeWithVersion(LifecycleOwner owner, final VersionedObserver<T> observer) {
|
||||
observe(owner, new Observer<VersionedData<T>>() {
|
||||
private int lastHandledVersion = -1; // 记录上次处理的版本号
|
||||
|
||||
@Override
|
||||
public void onChanged(VersionedData<T> newData) {
|
||||
if (newData == null) return;
|
||||
// 仅处理版本号高于上次的新数据
|
||||
if (newData.getVersion() > lastHandledVersion) {
|
||||
lastHandledVersion = newData.getVersion();
|
||||
observer.onNewData(newData.getData());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 版本化观察者接口,用于接收新数据
|
||||
*/
|
||||
public interface VersionedObserver<T> {
|
||||
void onNewData(T data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user