网上给的防止数据倒灌的很多都有内存泄露风险,原因在于Observer对象变了,在removeObservers的时候就无法把Observer移除掉,在多次调用observe之后就会出现内存泄露问题
下面的方案修改面很小,只需要用TimeSequenceLiveData替换掉MutableLiveData就好了,源码如下:
public class TimeSequenceLiveData<T> extends MutableLiveData<T> {
private long mLastSetValueTime;
//key为newObserver,value为包装的Observer
private final ConcurrentHashMap<Observer<? super T>, ObserverWrapper<T>> mObserverMap = new ConcurrentHashMap<>();
public TimeSequenceLiveData() {
}
public TimeSequenceLiveData(T value) {
super(value);
}
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
Observer<T> newObserver = new Observer<T>() {
private final long initTime = System.currentTimeMillis();
@Override
public void onChanged(@Nullable T t) {
if (initTime < mLastSetValueTime) {
observer.onChanged(t);
}
}
};
mObserverMap.put(newObserver, new ObserverWrapper<>(owner, newObserver));
super.observe(owner, newObserver);
}
@Override
public void removeObservers(@NonNull LifecycleOwner owner) {
super.removeObservers(owner);
HashSet<Observer<? super T>> removeKeySet = new HashSet<>();
for (Observer<? super T> observer : mObserverMap.keySet()) {
ObserverWrapper<T> tObserverWrapper = mObserverMap.get(observer);
if (null == tObserverWrapper) {
continue;
}
if (tObserverWrapper.mLifecycleOwnerWeakReference.get() == owner) {
super.removeObserver(tObserverWrapper.mWrapperObserver);
removeKeySet.add(observer);
}
}
for (Observer<? super T> observer : removeKeySet) {
mObserverMap.remove(observer);
}
}
@Override
public void setValue(T value) {
mLastSetValueTime = System.currentTimeMillis();
super.setValue(value);
}
@Override
public void removeObserver(@NonNull Observer<? super T> observer) {
ObserverWrapper<T> tObserverWrapper = mObserverMap.get(observer);
if (null != tObserverWrapper) {
super.removeObserver(tObserverWrapper.mWrapperObserver);
mObserverMap.remove(observer);
} else {
super.removeObserver(observer);
}
}
private static class ObserverWrapper<T> {
@NonNull
private final WeakReference<LifecycleOwner> mLifecycleOwnerWeakReference;
@NonNull
private final Observer<? super T> mWrapperObserver;
public ObserverWrapper(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
mLifecycleOwnerWeakReference = new WeakReference<>(owner);
mWrapperObserver = observer;
}
}
}