diff --git a/lib_social/src/main/java/com/android/sdk/social/wechat/SingleLiveData.java b/lib_social/src/main/java/com/android/sdk/social/wechat/SingleLiveData.java index b96a994..a0a90e3 100644 --- a/lib_social/src/main/java/com/android/sdk/social/wechat/SingleLiveData.java +++ b/lib_social/src/main/java/com/android/sdk/social/wechat/SingleLiveData.java @@ -4,14 +4,21 @@ import android.arch.lifecycle.LifecycleOwner; import android.arch.lifecycle.MediatorLiveData; import android.arch.lifecycle.Observer; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; -import java.util.WeakHashMap; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; -class SingleLiveData extends MediatorLiveData { +import timber.log.Timber; + +public class SingleLiveData extends MediatorLiveData { private int mVersion = 0; - private final WeakHashMap, Observer> cache = new WeakHashMap<>(); + private final List>> mWrapperObserverList = new ArrayList<>(); + @Override public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) { @@ -23,20 +30,6 @@ class SingleLiveData extends MediatorLiveData { super.observeForever(getOrNewObserver(observer, mVersion)); } - private Observer getOrNewObserver(@NonNull Observer observer, int observerVersion) { - Observer wrapper = cache.get(observer); - - if (wrapper == null) { - wrapper = t -> { - if (observerVersion < mVersion) { - observer.onChanged(t); - } - }; - cache.put(observer, wrapper); - } - return wrapper; - } - @Override public void setValue(T value) { mVersion++; @@ -45,10 +38,61 @@ class SingleLiveData extends MediatorLiveData { @Override public void removeObserver(@NonNull Observer observer) { - Observer wrapper = cache.remove(observer); + Observer wrapper = findWrapper(observer); + Timber.d("removeObserver() called with: observer = [" + observer + "], wrapper = [" + wrapper + "]"); if (wrapper != null) { super.removeObserver(wrapper); } + } + + private ObserverWrapper findWrapper(Observer observer) { + ListIterator>> iterator = mWrapperObserverList.listIterator(); + + ObserverWrapper target = null; + + while (iterator.hasNext()) { + WeakReference> next = iterator.next(); + ObserverWrapper item = next.get(); + if (item == null) { + iterator.remove(); + } else if (item.mOrigin == observer) { + target = item; + } + } + + return target; + } + + private Observer getOrNewObserver(@NonNull Observer observer, int observerVersion) { + ObserverWrapper wrapper = findWrapper(observer); + + if (wrapper == null) { + wrapper = new ObserverWrapper<>(observerVersion, observer); + mWrapperObserverList.add(new WeakReference<>(wrapper)); + } + + Timber.d("getOrNewObserver() called with: observer = [" + observer + "], observerVersion = [" + observerVersion + "], wrapper = [" + wrapper + "]"); + + return wrapper; + } + + private class ObserverWrapper implements Observer { + + private final int mObserverVersion; + + private final Observer mOrigin; + + private ObserverWrapper(int observerVersion, Observer origin) { + mObserverVersion = observerVersion; + mOrigin = origin; + } + + @Override + public void onChanged(@Nullable E t) { + if (mObserverVersion < mVersion && mOrigin != null) { + mOrigin.onChanged(t); + } + } }