关于不接收订阅之前的消息的思考
你好:如果不接收之前的消息,我们让刚注册的观察者的onChanged方法不执行应该就可以了吧,用个标志位控制一下比如。
private class BusMutableLiveData<T> extends MutableLiveData<T>{
/**
* 是否需要更新数据,当主动调用setValue或者postValue的时候才触发
*/
private boolean isChangeData = false;
@Override
public void setValue(T value) {
isChangeData = true;
super.setValue(value);
}
@Override
public void postValue(T value) {
isChangeData = true;
super.postValue(value);
}
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
super.observe(owner, new ObserverWrapper<T>(observer,this));
}
}
private class ObserverWrapper<T> implements Observer<T>{
private Observer<? super T> mObserver;
private BusMutableLiveData<T> mLiveData;
public ObserverWrapper(Observer<? super T> observer,BusMutableLiveData<T> liveData) {
mObserver = observer;
mLiveData = liveData;
}
@Override
public void onChanged(T t) {
if(mLiveData.isChangeData&&mObserver!=null){
mObserver.onChanged(t);
}
}
}
这种方法貌似不行,比如我按你的类,定义了一个LiveData,我调了setValue,这个时候isChangeData = true了,这个时候我再添加一个Observer,isChangeData是为true的,Observer会收到消息,没起到任何拦截的作用啊
初始化的方法是这样的
public synchronized <T> MutableLiveData<T> with(String target, Class<T> type,boolean isFirstChange) {
if (!mBus.containsKey(target)) {
mBus.put(target, new BusMutableLiveData<>());
}
BusMutableLiveData liveData = mBus.get(target);
liveData.isChangeData = isFirstChange;
return (MutableLiveData<T>)liveData;
}
public synchronized <T> MutableLiveData<T> with(String target, Class<T> type) {
return (MutableLiveData<T>) with(target,Object.class,false);
}
新建通道或者从Map中找到通道都会把isChangeData 默认置为false。或者如果想接收可以传入true。
这种场景会有问题:你是假设with和observe是连续调用的,但是如果我先调用with,持有这个Observable,过一段时间再去调用observe,在这期间你可能已经多次调用了setValue或者postValue,所以就起不到任何拦截作用了。 即使没有这么极端,with的调用和最后真正执行到把Observable注册上去,是有时间差的,你没法保证这段时间isChangeData一直为false,所以是有问题的
那如果我在注册的时候在给他置为false呢
private class ObserverWrapper<T> implements Observer<T>{
private Observer<? super T> mObserver;
private BusMutableLiveData<T> mLiveData;
public ObserverWrapper(Observer<? super T> observer,BusMutableLiveData<T> liveData) {
mObserver = observer;
mLiveData = liveData;
mLiveData.isChangeData = false;
}
@Override
public void onChanged(T t) {
if(mLiveData.isChangeData&&mObserver!=null){
mObserver.onChanged(t);
}
}
}
这样是有问题的,livedata和Observer的关系是一对多的关系,在注册某个Observer的时候去修改mLiveData.isChangeData会影响到其他Observer,考虑这种场景:你调用了LiveData.setValue,这个值还没有传递到Observer的时候你去注册了一个新的Observer,这会导致其他本应该收到消息的Observer收不到消息了
非常感谢回复,我又改了一下,抄系统的也弄个version,每次注册把当前的version给他
private class BusMutableLiveData<T> extends MutableLiveData<T>{
int mCurrentVersion;
/**
* 是否需要更新数据,当主动调用setValue或者postValue的时候才触发
*/
@Override
public void setValue(T value) {
mCurrentVersion++;
super.setValue(value);
}
@Override
public void postValue(T value) {
mCurrentVersion++;
super.postValue(value);
}
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
super.observe(owner, new ObserverWrapper<T>(observer,mCurrentVersion,this));
}
}
private class ObserverWrapper<T> implements Observer<T>{
private Observer<? super T> mObserver;
private int mVersion;
private BusMutableLiveData<T> mLiveData;
public ObserverWrapper(Observer<? super T> observer,int version,BusMutableLiveData<T> liveData) {
mObserver = observer;
mVersion = version;
mLiveData = liveData;
}
@Override
public void onChanged(T t) {
if(mLiveData.mCurrentVersion>mVersion&&mObserver!=null){
mObserver.onChanged(t);
}
}
}