LiveDataBus 的实现比你想象中的简单
code小生
一个专注大前端领域的技术平台
公众号回复 Android
加入安卓技术群
作者:BugRui
链接:https://www.jianshu.com/p/9b00422fbcc1
声明:本文已获 BugRui
授权发表,转发等请联系原作者授权
为什么要用LiveData实现事件总线呢?
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
LiveData 具有生命周期感知能力,确保界面符合数据状态,不会发生内存泄露,不会因 Activity停止而导致崩溃,不再需要手动处理生命周期,数据始终保持最新状态
LiveData 我就不多做介绍了,LiveData已经有很多,很详细的文章,接下来谈谈如何使用LiveData实现事件总线
使用LiveData实现事件总线的难点在于LiveData 为了在视图控制器发生重建后,能够 自动倒灌 所观察的 LiveData 的最后一次数据,LiveData 被设计为粘性事件,在此之前我看了很多关于LiveDataBus的文章,关于非粘性 LiveData 的实现,网上存在通过 “事件包装类”和 “反射干预 LastVersion” 两种方式来解决.
LiveDataBus的实现真的需要这么麻烦吗?不,我觉得不需要。
接下来分享一下 我的实现思路
定义一个HashMap用于保存不同的消息通道
private val liveDataMap = HashMap<String, MutableLiveData>()
LiveData 为了在视图控制器发生重建后,能够 自动倒灌 所观察的 LiveData 的最后一次数据,LiveData 被设计为粘性事件的解决方案
解决方案:
为了避免收到重复的事件,这里我使用的解决方案是每次都new一个新的MutableLiveData替换原来的MutableLiveData,这样一来,每次配置更改的时候都会new一个新的MutableLiveData,也就不会收到上一个MutableLiveData的消息,但是多处订阅的时候只需要使用不同的tag,否则只有最后一个订阅的地方收到
fun with(tag: String): LiveData? { liveDataMap.put(tag,MutableLiveData()) return liveDataMap[tag] }
订阅事件,仅更新处于活动生命周期状态的应用程序组件观察者
LiveDataBus.with(tag).observe(this, Observer { //收到消息 })
订阅的时候,observe仅更新处于活动生命周期状态的应用程序组件观察者,如果需要不受生命周期的影响,只要数据更新就会收到通知可以使用observeForever,这意味着给定的观察者将接收所有事件,并且永远不会被自动删除。需要手动调用removeObserver(Observer)来停止这个LiveData
/** * Adds the given observer to the observers list. This call is similar to * {@link LiveData#observe(LifecycleOwner, Observer)} with a LifecycleOwner, which * is always active. This means that the given observer will receive all events and will never * be automatically removed. You should manually call {@link #removeObserver(Observer)} to stop * observing this LiveData. * While LiveData has one of such observers, it will be considered * as active. * * If the observer was already added with an owner to this LiveData, LiveData throws an * {@link IllegalArgumentException}. * * @param observer The observer that will receive the events */ @MainThread public void observeForever(@NonNull Observer observer) { assertMainThread("observeForever"); AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) { throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } wrapper.activeStateChanged(true); }
使用observeForever 订阅,不受生命周期的影响,只要数据更新就会收到通知
LiveDataBus.with(tag).observeForever(this, Observer { //收到消息 })
事件的发送
fun send(tag: String, t: Any? = null) { if (!liveDataMap.containsKey(tag) ) return liveDataMap[tag]?.postValue(t) } // 发送 LiveDataBus.send(tag)
LiveDataBus 的源码可以直接拷贝使用,也可以前往作者的 GitHub 仓库查看下载: https://github.com/BugRui/LiveDataBus