Closed Lumberjack100 closed 3 years ago
第一 : 入参 observer 进行 Hash 运算得到的 observeKey 与注册 Observer 时得到的observeKey 不一样,这个检测一下是同一个observer 对象。 第二:observeForever() 是需要自己手动注册和删除的,observe 会在activity destory的时候会回调删除;
第三:感觉这样写有点太复杂,本来倒灌的原因就是新监听的oberver的版本是从-1 开始计算;可以自己维护一个版本号,根本就不需要存什么observer
@themaster-gh
1.上述你的描述 未提供诊断的数据 且存在歧义,缺乏一致的前提来核对和确认,
2.我自行通过 Log 测试一番,无法复现你说的 Observe 无法 remove 的问题,V5 版的源码设计者在 removeObserver 中,通过 ObserveKey 试图获取的是 ForeverObserver,而非 Observer,当 foreverObserver 不存在时,便默认去 remove observer。
3.V5 源码的设计确实比较复杂,请以最新源码为准。
以下是 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);
}
}
你好,我在阅读源码试着理解版本代码演进的逻辑,但是我发现 V5版本还是存在HashMap恒久存在,注册的 Observer 越多,占用的内存越大问题
发现在退出页面调用removeObserver 方法时,入参 observer 进行 Hash 运算得到的 observeKey 与注册 Observer 时得到的observeKey 不一样