我们先在LiveData2Activity 中 setValue
class LiveData2Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
// 先订阅 后发送消息
MyLiveData.value1.observe(this, {
Toast.makeText(this, it, Toast.LENGTH_SHORT).show()
})
findViewById<View>(R.id.button).setOnClickListener {
MyLiveData.value1.value = "LiveData2Activity发送的消息"
}
}
}
让后在LiveData3Activity订阅接收消息
class LiveData3Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
// 产生的数据粘性 先发送后订阅 可以收到消息
MyLiveData.value1.observe(this, {
Toast.makeText(this, it, Toast.LENGTH_SHORT).show()
})
}
先订阅 后 setValue 收到消息 正确
先setValue 后订阅 也收到了消息 数据粘性 不正确
如何去掉数据粘性 : hook 反射 动态修改源码 就可以去除
/**
* 单例模式
* 去除粘性
*/
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() {
this.isStick = isStick
}
// 我是先执行
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, observer)
if (isStick) {
} else {
hook(observer)
}
}
private fun <T> hook(observer: Observer<in T>) {
// 获取mLastVersion
val liveDataClass = LiveData::class.java
// getDeclaredField是可以获取一个类的所有字段.
// getField只能获取类的public 字段.
val mObserversField = liveDataClass.getDeclaredField("mObservers")
mObserversField.isAccessible = true //private 修饰也可以访问
val mObserversObject = mObserversField.get(this)
// 获取 private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
val mObserversClass = mObserversObject.javaClass
// 获取 mObservers 的 get方法 protected Entry<K, V> get(K k){}
val get = mObserversClass.getDeclaredMethod("get", Any::class.java)
get.isAccessible = true
// 执行get方法
val invoke = get.invoke(mObserversObject, observer)
// 获取 entry 中 的 value
var observerWrapper: Any? = null
if (invoke != null && invoke is Map.Entry<*, *>) {
observerWrapper = invoke.value
}
if (observerWrapper == null) {
throw NullPointerException("observerWrapper is null")
}
// 得到observerWrapper的类对象
val superclass = observerWrapper.javaClass.superclass
val mLastVersionField = superclass.getDeclaredField("mLastVersion")
mLastVersionField.isAccessible = true
// 得到mVersion
val mVersionField = liveDataClass.getDeclaredField("mVersion")
mVersionField.isAccessible = true
// 版本对齐
val versionValue = mVersionField.get(this)
mLastVersionField.set(observerWrapper, versionValue)
}
}
}