ProtectedUnPeekLiveDataV5疑问
Lumberjack100 opened this issue · comments
Lumberjack commented
tzq commented
第一 : 入参 observer 进行 Hash 运算得到的 observeKey 与注册 Observer 时得到的observeKey 不一样,这个检测一下是同一个observer 对象。
第二:observeForever() 是需要自己手动注册和删除的,observe 会在activity destory的时候会回调删除;
第三:感觉这样写有点太复杂,本来倒灌的原因就是新监听的oberver的版本是从-1 开始计算;可以自己维护一个版本号,根本就不需要存什么observer
KunMinX commented
@themaster-gh
1.上述你的描述 未提供诊断的数据 且存在歧义,缺乏一致的前提来核对和确认,
2.我自行通过 Log 测试一番,无法复现你说的 Observe 无法 remove 的问题,V5 版的源码设计者在 removeObserver 中,通过 ObserveKey 试图获取的是 ForeverObserver,而非 Observer,当 foreverObserver 不存在时,便默认去 remove observer。
3.V5 源码的设计确实比较复杂,请以最新源码为准。
KunMinX commented
以下是 V6.1 简版代码
public class ProtectedUnPeekLiveData<T> extends LiveData<T> {
private final ConcurrentHashMap<Observer<? super T>, ObserverProxy> observerMap = new ConcurrentHashMap();
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
Observer<? super T> observer1 = getObserverProxy(observer);
if (observer1 != null) {
super.observe(owner, observer1);
}
}
@Override
public void observeForever(@NonNull Observer<? super T> observer) {
Observer<? super T> observer1 = getObserverProxy(observer);
if (observer1 != null) {
super.observeForever(observer1);
}
}
private Observer<? super T> getObserverProxy(Observer<? super T> observer) {
if (observerMap.containsKey(observer)) {
return null;
} else {
ObserverProxy proxy = new ObserverProxy(observer);
observerMap.put(observer, proxy);
return proxy;
}
}
private class ObserverProxy implements Observer<T> {
public final Observer<? super T> target;
public boolean allow;
public ObserverProxy(Observer<? super T> target) {
this.target = target;
}
@Override
public void onChanged(T t) {
if (allow) {
allow = false;
target.onChanged(t);
}
}
}
@Override
protected void setValue(T value) {
for (Map.Entry<Observer<? super T>, ObserverProxy> entry : observerMap.entrySet()) {
entry.getValue().allow = true;
}
super.setValue(value);
}
@Override
public void removeObserver(@NonNull Observer<? super T> observer) {
observerMap.remove(observer);
super.removeObserver(observer);
}
}