From 7682edda28c244fe2c6b52a458a127e28ef99e54 Mon Sep 17 00:00:00 2001 From: Zhanty Date: Tue, 16 Jul 2019 20:34:31 +0800 Subject: [PATCH] optimize SingleLiveData --- .../android/base/app/aac/SingleLiveData.java | 61 +++++++++++++++++++ .../android/base/app/aac/SingleLiveData.kt | 36 ----------- .../java/com/android/base/kotlin/MenuEx.kt | 24 ++++++++ .../sdk/social/wechat/SingleLiveData.java | 43 ++++++++----- 4 files changed, 113 insertions(+), 51 deletions(-) create mode 100644 lib_base/src/main/java/com/android/base/app/aac/SingleLiveData.java delete mode 100644 lib_base/src/main/java/com/android/base/app/aac/SingleLiveData.kt diff --git a/lib_base/src/main/java/com/android/base/app/aac/SingleLiveData.java b/lib_base/src/main/java/com/android/base/app/aac/SingleLiveData.java new file mode 100644 index 0000000..2b7bbb2 --- /dev/null +++ b/lib_base/src/main/java/com/android/base/app/aac/SingleLiveData.java @@ -0,0 +1,61 @@ +package com.android.base.app.aac; + +import android.arch.lifecycle.LifecycleOwner; +import android.arch.lifecycle.MediatorLiveData; +import android.arch.lifecycle.Observer; +import android.support.annotation.NonNull; + +import java.util.Map; +import java.util.WeakHashMap; + +import timber.log.Timber; + +public class SingleLiveData extends MediatorLiveData { + + private int mVersion = 0; + + private final Map, Observer> cache = new WeakHashMap<>(); + + @Override + public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) { + super.observe(owner, getOrNewObserver(observer, mVersion)); + } + + @Override + public void observeForever(@NonNull Observer observer) { + super.observeForever(getOrNewObserver(observer, mVersion)); + } + + @Override + public void setValue(T value) { + mVersion++; + super.setValue(value); + } + + @Override + public void removeObserver(@NonNull Observer observer) { + Observer wrapper = cache.remove(observer); + Timber.d("removeObserver() called with: observer = [" + observer + "], wrapper = [" + wrapper + "]"); + if (wrapper != null) { + super.removeObserver(wrapper); + } + } + + 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); + } + + Timber.d("getOrNewObserver() called with: observer = [" + observer + "], observerVersion = [" + observerVersion + "], wrapper = [" + wrapper + "]"); + + return wrapper; + } + +} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/app/aac/SingleLiveData.kt b/lib_base/src/main/java/com/android/base/app/aac/SingleLiveData.kt deleted file mode 100644 index b256889..0000000 --- a/lib_base/src/main/java/com/android/base/app/aac/SingleLiveData.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.android.base.app.aac - -import android.arch.lifecycle.LifecycleOwner -import android.arch.lifecycle.MediatorLiveData -import android.arch.lifecycle.Observer - -/** https://github.com/Shopify/livedata-ktx */ -class SingleLiveData : MediatorLiveData() { - - private var _version = 0 - private val version: Int get() = _version - - override fun observe(owner: LifecycleOwner, observer: Observer) { - val observerVersion = version - super.observe(owner, Observer { - if (observerVersion < version) { - observer.onChanged(it) - } - }) - } - - override fun observeForever(observer: Observer) { - val observeSinceVersion = version - super.observeForever { - if (version > observeSinceVersion) { - observer.onChanged(it) - } - } - } - - override fun setValue(value: T?) { - _version++ - super.setValue(value) - } - -} \ No newline at end of file diff --git a/lib_base/src/main/java/com/android/base/kotlin/MenuEx.kt b/lib_base/src/main/java/com/android/base/kotlin/MenuEx.kt index 022a49a..6ce25af 100644 --- a/lib_base/src/main/java/com/android/base/kotlin/MenuEx.kt +++ b/lib_base/src/main/java/com/android/base/kotlin/MenuEx.kt @@ -1,7 +1,31 @@ package com.android.base.kotlin +import android.support.v7.widget.PopupMenu +import android.view.Menu import android.view.MenuItem +fun PopupMenu.setMenus(items: Array): PopupMenu { + for (i in 0 until items.size) { + menu.add(Menu.NONE, i, i, items[i]) + } + return this +} + +fun PopupMenu.setMenus(items: Array, ids: IntArray): PopupMenu { + for (i in 0 until items.size) { + menu.add(Menu.NONE, ids[i], i, items[i]) + } + return this +} + +fun PopupMenu.onMenuItemClick(listener: (id: Int) -> Unit): PopupMenu { + setOnMenuItemClickListener { + listener(it.itemId) + true + } + return this +} + fun MenuItem.alwaysShow(): MenuItem { setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) return this 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 3f03d46..b96a994 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 @@ -5,32 +5,36 @@ import android.arch.lifecycle.MediatorLiveData; import android.arch.lifecycle.Observer; import android.support.annotation.NonNull; +import java.util.WeakHashMap; + class SingleLiveData extends MediatorLiveData { private int mVersion = 0; + private final WeakHashMap, Observer> cache = new WeakHashMap<>(); + @Override public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) { - - final int observerVersion = mVersion; - - super.observe(owner, t -> { - if (observerVersion < mVersion) { - observer.onChanged(t); - } - }); + super.observe(owner, getOrNewObserver(observer, mVersion)); } @Override public void observeForever(@NonNull Observer observer) { + super.observeForever(getOrNewObserver(observer, mVersion)); + } - final int observerVersion = mVersion; - - super.observeForever(t -> { - if (observerVersion < mVersion) { - observer.onChanged(t); - } - }); + 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 @@ -39,4 +43,13 @@ class SingleLiveData extends MediatorLiveData { super.setValue(value); } + @Override + public void removeObserver(@NonNull Observer observer) { + Observer wrapper = cache.remove(observer); + if (wrapper != null) { + super.removeObserver(wrapper); + } + + } + } \ No newline at end of file