先上代码:
Kotlin
object LiveDataBusKT {
// private val bus: MutableMap<String, BusMutableLiveData<Any>> by lazy { HashMap() }
private val MAX_BUS_COUNT = 100 // 最大允许的 bus 对象数量
private val bus: LruCache<String, BusMutableLiveData<Any>> = LruCache(MAX_BUS_COUNT)
//暴露一个线程安全的,给外界注册,订阅者关系
@Synchronized
fun <T>with(key:String,type:Class<T>,isStick: Boolean =true):BusMutableLiveData<T>{
var liveData = bus.get(key)
if (liveData == null) {
liveData = BusMutableLiveData(isStick)
bus.put(key, liveData)
}
// if (!bus.containsKey(key)){
// bus[key] = BusMutableLiveData(isStick)
// }
return bus[key] as BusMutableLiveData<T>
}
class BusMutableLiveData<T> private constructor() :MutableLiveData<T>(){
var isStick =false //开启,关闭 粘性
//次构造
constructor(isStick: Boolean):this(){
this.isStick =isStick
}
//hook
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, observer)
if (!isStick){
hook(observer =observer)
}else{
}
}
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)
}
}
}
为了开启,关闭粘性事件,使用了 isStick 控制。
通过继承 MutableLiveData,在observe的时候hook 获取 mLastVersion 和mVersion,进行版本对齐