前言:提及事件总线常常使用org.greenrobot:eventbus框架,而本文通过LiveData即可轻松实现Eventbus。 实现:这里只定义了1个LiveData,通过TAG作事件的区分。 1、定义事件基类
data class BaseEvent<T>(
val tag: Int,
val msg: T
)
2、定义事件操作类
object EventBus{
val onEventLiveData = MutableLiveData<BaseEvent<*>>()
const val TAG_CONNECT_PRINTER_SUCCESS = 1
}
3、注册事件
EventBus.onEventLiveData.observe(this, Observer {
if (it.tag == EventBus.TAG_CONNECT_PRINTER_SUCCESS) {
mViewModel.showMsgToastLiveData.value = "连接打印机成功"
}
})
4、发送事件
EventBus.onEventLiveData.setValue(BaseEvent(EventBus.TAG_CONNECT_PRINTER_SUCCESS, true))
问题:由于LiveData本身是具有数据粘性的(即页面A、B都注册了同一事件,而在A中更新事件后进入B页面则立即会收到更新事件,然而实际场景我们只关注页面注册事件的更新事件,而之前的不需要) 原因:这是LiveData框架本身的设计原因(即注册时给订阅者和LiveData记录初始版本号,更新LiveData时其版本号加1,当订阅者的版本比LiveData小时则更新,而当有新的注册时,订阅者版本为初始值,LiveData为更新后的值,大于初始值所有就收到更新) 方案:注册的时候给订阅者版本号为LiveData的版本号即可。
/**
* 非粘性LiveData
*/
class UnPeekMutableLiveData<T> : MutableLiveData<T>() {
private val START_VERSION = -1
private val mCurrentVersion = AtomicInteger(START_VERSION)
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, createObserverWrapper(observer, mCurrentVersion.get()))
}
override fun observeForever(observer: Observer<in T>) {
super.observeForever(createObserverForeverWrapper(observer, mCurrentVersion.get()))
}
fun observeSticky(owner: LifecycleOwner, observer: Observer<T>) {
super.observe(owner, createObserverWrapper(observer, START_VERSION))
}
fun observeStickyForever(observer: Observer<in T>) {
super.observeForever(createObserverForeverWrapper(observer, START_VERSION))
}
override fun setValue(value: T) {
mCurrentVersion.getAndIncrement()
super.setValue(value)
}
override fun removeObserver(observer: Observer<in T>) {
if (TextUtils.isEmpty(observer.toString())) {
super.removeObserver(observer)
} else {
super.removeObserver(createObserverWrapper(observer, START_VERSION))
}
}
private fun createObserverForeverWrapper(
observer: Observer<in T>,
version: Int
): MyObserverWrapper<T> {
return MyObserverWrapper(observer, mCurrentVersion, version, true)
}
private fun createObserverWrapper(
observer: Observer<in T>,
version: Int
): MyObserverWrapper<T> {
return MyObserverWrapper(observer, mCurrentVersion, version, false)
}
fun clear() {
super.setValue(null)
}
}
class MyObserverWrapper<T> constructor(
private val mObserver: Observer<in T>, private val mLiveDataVersion: AtomicInteger,
private val mVersion: Int, private val mIsForever: Boolean): Observer<T> {
override fun onChanged(t: T?) {
if (mLiveDataVersion.get() > mVersion) {
mObserver.onChanged(t)
}
}
override fun equals(o: Any?): Boolean {
if (this === o) {
return true
}
if (o == null || javaClass != o.javaClass) {
return false
}
val that = o as MyObserverWrapper<*>
return Objects.equals(mObserver, that.mObserver)
}
override fun hashCode(): Int {
return Objects.hash(mObserver)
}
override fun toString(): String {
return if (mIsForever) "IS_FOREVER" else ""
}
}
只需将EventBus里的MutableLiveData替换为UnPeekMutableLiveData即可
|