具体参考
https://www.cnblogs.com/meituantech/p/9376449.html
观察者模式
多个果商订阅了某个果农的果子,果子熟了告诉我。
几天后果子熟了,果农一个个通知果商来拿货
发布/订阅模式
发布者只负责把信息发布到调度中心,至于这信息有没有人处理,怎么样处理,则不关心。
附加上代码
/**
* 替换 EventBus RxBus
* 最优一点 自动跟组件生命周期绑定一起 可以参考Lifecycle
*
* 观察者模式 1对多的关系 观察者A -》 订阅 -》 被观察者B
* 《- 触发事件《-
*
*
* 发布者只管发布消息到调度中心 这个消息是否需要 不需要管
* 发布订阅模式 1对多的关系 订阅者A -》 订阅 -》 调度中心B <=发布消息<= 发布者
* 《- 触发事件《-
* lahm
*/
class LiveDataBus {
private var bus: HashMap<String, BusMutableLiveData<Any>>? = null
constructor() {
bus = HashMap()
}
//泛型方法 type主要用于取泛型类型
fun <T> with(key: String, type: Class<T>, isViscidity: Boolean): MutableLiveData<T> {
if (bus == null) {
throw NullPointerException("bus can not be null!")
}
if (!bus!!.containsKey(key)) {
bus!![key] = BusMutableLiveData(isViscidity)
}
return bus!![key] as (MutableLiveData<T>)
}
fun <T> with(key: String, type: Class<T>): MutableLiveData<T> {
return with(key, type, false)
}
//普通
fun with(key: String): MutableLiveData<Any> {
return with(key, Any::class.java, false)
}
//粘性
fun with(key: String, isViscidity: Boolean): MutableLiveData<Any> {
return with(key, Any::class.java, isViscidity)
}
companion object {
val KEY_GOTO_HOME = "go_home"//跳转首页逻辑
fun get(): LiveDataBus {//单例的另外一种写法
return Companion.SingletonHolder.DEFAULT_BUS
}
class SingletonHolder {
companion object {
val DEFAULT_BUS = LiveDataBus()
}
}
class ObserverWrapper<T>(val observer: Observer<T>?) : Observer<T> {
override fun onChanged(t: T?) {
if (observer != null) {
if (isCallOnObserve()) {
return
}
observer.onChanged(t)
}
}
fun isCallOnObserve(): Boolean {
val stackTrace = Thread.currentThread().stackTrace
if (stackTrace != null && stackTrace.isNotEmpty()) {
for (element in stackTrace) {
if ("android.arch.lifecycle.LiveData" == element.className && "observeForever" == element.methodName) {
return true
}
}
}
return false
}
}
class BusMutableLiveData<T>() : MutableLiveData<T>() {
private val observerMap: HashMap<Observer<T>, Observer<T>> = HashMap()
private var isViscidity = false//是否粘性
constructor(isViscidity: Boolean) : this() {
this.isViscidity = isViscidity
}
override fun observe(owner: LifecycleOwner, observer: Observer<T>) {
super.observe(owner, observer)
if (!isViscidity) {
try {
hook(observer)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
override fun observeForever(observer: Observer<T>) {
if (!observerMap.containsKey(observer)) {
observerMap[observer] = ObserverWrapper(observer)
}
super.observeForever(observer)
}
/**
* 为了防止粘性消息 所以此处用hook处理 分发机制 需要对源码有详细的了解
*/
fun hook(observer: Observer<T>) {
val classLiveData: Class<LiveData<*>> = LiveData::class.java
//反射获取 LiveData中的 SafeIterableMap<Observer<T>, ObserverWrapper> mObservers
val fieldObservers = classLiveData.getDeclaredField("mObservers")
fieldObservers.isAccessible = true
val objectObservers = fieldObservers.get(this)
val classObservers = objectObservers.javaClass
//反射获取 SafeIterableMap中的get方法
val methodGet = classObservers.getDeclaredMethod("get", Any::class.java)
methodGet.isAccessible = true
//执行get方法
val objectWrapperEntry = methodGet.invoke(objectObservers, observer)
var objectWrapper: Any? = null
if (objectWrapperEntry is Map.Entry<*, *>) {
objectWrapper = (objectWrapperEntry as Map.Entry<*, *>).value
}
if (objectWrapper == null) {
throw NullPointerException("Wrapper can not be bull!")
}
val classObserverWrapper = objectWrapper.javaClass.superclass
val fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion")
fieldLastVersion.isAccessible = true
//get livedata's version
val fieldVersion = classLiveData.getDeclaredField("mVersion")
fieldVersion.isAccessible = true
val objectVersion = fieldVersion.get(this)
//set wrapper's version
fieldLastVersion.set(objectWrapper, objectVersion)
}
}
}
}
发送信息
LiveDataBus.get().with(LiveDataBus.KEY_GOTO_HOME, UpdateGotoViewEvent::class.java).value = UpdateGotoViewEvent(0,0)
接收信息
LiveDataBus.Companion.get().with(LiveDataBus.Companion.getKEY_GOTO_HOME(), UpdateGotoViewEvent.class)
.observe(this, event -> {
if (event != null) {
...
}
});
UpdateGotoViewEvent类代码
/**
* Created by lahm
* 跳转界面
* *@param oneIndex 1级下标
* *@param twoIndex 2级下标
*/
class UpdateGotoViewEvent(var oneIndex: Int, var twoIndex: Int)
如果是发送简单的类型比如Boolean
直接替换就好
LiveDataBus.get().with(LiveDataBus.KEY_DOWNLOAD_FINISH, Boolean::class.java).value = true
LiveDataBus.get().with(LiveDataBus.KEY_DOWNLOAD_FINISH, Boolean::class.java) .observe(this, Observer { if (it!!) { ... } })
导包
import android.arch.lifecycle.Observer
粘性:先发送消息再订阅,还是能接收到消息
非粘性:先订阅再发送消息,才能接收到