什么叫粘性事件
LiveData使用篇Jetpack 中的 LiveData - 使用篇_简单不一定不好的博客-优快云博客后再进一步了解LiveData。观察者和被观察者,正常情况下观察者先注册,被观察者再发送观察事件;所以粘性事件可以理解为观察者模式的升级,可以让观察者与被观察者之间更加的粘合,即是可先发送观察者事件,再注册观察者。
粘性事件测试
ViscosityActivity
class ViscosityActivity : AppCompatActivity() {
private var textView: TextView? = null
private var num = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_viscosity)
textView = findViewById(R.id.textView)
MyLiveData.data.observe(this, { msg ->
Log.d("liveData", "界面显示:$msg")
textView?.text = msg
})
MyLiveData.data.value = "Default"
findViewById<Button>(R.id.bt).setOnClickListener {
MyLiveData.data.value = "Default:${++num}"
}
findViewById<Button>(R.id.bt2).setOnClickListener {
startActivity(Intent(this,ViscosityActivity2::class.java))
}
}
}
ViscosityActivity2
class ViscosityActivity2 : AppCompatActivity() {
private var textView: TextView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_viscosity)
textView = findViewById(R.id.textView)
MyLiveData.data.observe(this, { msg ->
Log.d("liveData2", "界面显示:$msg")
textView?.text = msg
})
}
}
运行结果:ViscosityActivity 变化的结果 ViscosityActivity2 也显示一样
粘性事件分析
当被观察者 setValue 时候 mVersion 累加,
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
观察者包装类也封装一个 mLastVersion 初始化 -1 值
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
}
当 setValue 时候,对比被观察者 和观察者 version是否一致后再 onChanged 通知观察者
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
如何剔除粘性事件
object OkLiveDataBus {
//存放订阅者
private val bus: MutableMap<String, BusMutableLiveData<Any>> by lazy { HashMap() }
@Synchronized
fun <T> with(key: String, type: Class<T>, isStick: Boolean = true): BusMutableLiveData<T> {
if (!bus.containsKey(key)) {
bus[key] = BusMutableLiveData(isStick)
}
return bus[key] as BusMutableLiveData<T>
}
class BusMutableLiveData<T> private constructor() : MutableLiveData<T>() {
var isStick: Boolean = false//开启, 关闭黏性
//次构造
constructor(isStick: Boolean) : this() {
}
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, observer)
if (!isStick) {
hook(observer = observer)
Log.d("jetpack", "Kotlin版本的 不启用黏性")
} else {
Log.d("jetpack", "Kotlin版本的启用黏性")
}
}
}
private fun <T> hook(observer: Observer<in T>) {
//获取LiveDat 的类中的mObservers对象
val liveDataClass = LiveData::class.java
//SafeIterableMap <Observer<? super T>, ObserverWrapper>
val mObservers: Field = LiveData::class.java.getDeclaredField("mObservers")
mObservers.isAccessible = true//私有修饰也可以访问
//获取到这个成员变量的对象 Any == Object
val mObserversValue = mObservers.get(this)
//得到map 对象的 class对象
val mObserversClass: Class<*> = mObserversValue.javaClass
//获取到mObservers 对象的get方法
val get: Method = mObserversClass.getDeclaredMethod("get", Any::class.java)
get.isAccessible = true
//执行get方法
val invokeEntry: Any = get.invoke(mObserversValue, observer)
//取到entry中 的value
var observerWrapper: Any? = null
if (invokeEntry != null && invokeEntry is Map.Entry<*, *>) {
observerWrapper = invokeEntry.value
}
if (observerWrapper == null) {
throw NullPointerException("observerWrapper is null")
}
//得到observerWrapper的类对象
val supperClass: Class<*> = observerWrapper.javaClass.superclass
val mLastVersion: Field = supperClass.getDeclaredField("mLastVersion")
mLastVersion.isAccessible = true
//得到mVersion
val mVersion: Field = liveDataClass.getDeclaredField("mVersion")
mVersion.isAccessible = true
val mVersionValue = mVersion.get(this)
mLastVersion.set(observerWrapper, mVersionValue)
}
}
参考: