Android消息传递之基于RxJava实现一个EventBus - RxBus
前言:
上篇文章学习了Android事件总线管理开源框架EventBus,EventBus的出现大大降低了开发成本以及开发难度,今天我们就利用目前大红大紫的RxJava来实现一下类似EventBus事件总线管理,现在很多人都在说用这种方式来替代EventBus,今天我们从开发效率,开发难度等维度来分析一下到底能不能取代EventBus? 先回顾一下什么是EventBus?请看这篇文章Android消息传递之EventBus 3.0使用详解(三)
消息传递相关文章地址:
- Android消息传递之Handler消息机制
- Android消息传递之组件间传递消息
- Android消息传递之EventBus 3.0使用详解
- Android消息传递之基于RxJava实现一个EventBus - RxBus
需求:
虽然软件工程师就害怕听见“需求”这两个字,但是一切功能来源于需求,我们要基于RxJava实现一个publish/subscribe消息总线管理模型,这里假设你已经知道如何使用RxJava了。下面看看如何实现。
RxBus实现过程:
1.)build.gradle中添加RxJava、RxAndroid引用
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.2'
2.)声明一个管理事件总线的单例
public class RxBus {
private ConcurrentHashMap<Object, List<Subject>> subjectMapper = new ConcurrentHashMap<>();
private static volatile RxBus instance;
private RxBus() {
}
public static RxBus getInstance() {
RxBus inst = instance;
if (inst == null) {
synchronized (RxBus.class) {
inst = instance;
if (inst == null) {
inst = new RxBus();
instance = inst;
}
}
}
return inst;
}
}
考虑到RxBus单例很有可能多线程并发访问,这种存储事件总线采用ConcurrentHashMap
3.)订阅者实现注册/解除注册方法
注册/解注册都以一个tag为唯一标示,这里采用的是事件的Class为tag,来实现一个Event事件对象可以对应多个订阅者。
/**
* 注册
*
* @param tag
* @return
*/
public <T> Observable<T> register(@NonNull Class<T> tag) {
List<Subject> subjectList = subjectMapper.get(tag);
if (null == subjectList) {
subjectList = new ArrayList<>();
subjectMapper.put(tag, subjectList);
}
Subject<T, T> subject = PublishSubject.create();
subjectList.add(subject);
return subject;
} /**
* 解除注册
*
* @param tag
*/
public <T> void unregister(@NonNull Class<T> tag, @NonNull Observable observable) {
List<Subject> subjects = subjectMapper.get(tag);
if (null != subjects) {
subjects.remove(observable);
if (subjects.isEmpty()) {
subjectMapper.remove(tag);
}
}
}
4.)实现发送消息、清除所有注册
发送一个事件消息是通过获取当前事件下的订阅者列表,然后通过一个循环进行事件传递。至于事件运行在哪个线程中由订阅者决定。
/**
* 发送消息
*
* @param event
*/
public <T> void post(@NonNull Object event) {
List<Subject> subjectList = subjectMapper.get(event.getClass());
if (subjectList != null && !subjectList.isEmpty()) {
for (Subject subject : subjectList) {
subject.onNext(event);
}
}
} /**
* 清除订阅
*/
public void clear() {
if (subjectMapper.isEmpty()) {
return;
}
subjectMapper.clear();
}
5.)如何使用
事件的订阅者的注册和清除所有注册,订阅者没订阅一个类型的事件都要返回一个Observable对象,这也是个人觉得比较头疼的一件事,很难实现一个订阅者对应多个事件类型,而且解注册的时候也需要这些Observable对象进行一一解除。
private Observable<DataSynEvent> observable;
private void registerObservable() {
observable = RxBus.getInstance().register(DataSynEvent.class);
observable.observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<DataSynEvent>() {
@Override
public void call(DataSynEvent event) {
Log.e(TAG, "event--2-->" + event.getCount());
}
});
} private void unRegisterObservable() {
if (observable != null) {
RxBus.getInstance().unregister(DataSynEvent.class, observable);
}
}
事件的发送者发送事件,发送事件的处理还算比较友好,和EventBus很类似。
RxBus.getInstance().post(new DataSynEvent());
RxBus、EventBus 对比:
1.从引入依赖包对比
RxBus 需要引入两个包,EventBus需要引入一个,如果项目中没有使用到RxJava编程的话,并不能减少包的依赖。
2 .从开发难度上对比
上面也提到了实现RxBus是基于RxJava的,作为一个新的编程方式函数式编程,对开发者的要求多多少少提高了那么一点,而且每一个订阅都需要返回一个Observable,由订阅者写具体的代码 需要执行在哪个线程中,而EventBus 最新版本采用注解预编译的方式,订阅者注册解注册只需调用一个函数,而且通过注解的方式可以标明事件的优先级,接收事件运行在哪个线程,并且能够实现粘性事件,这些RxBus都需要进行二次开发。
3.)从开发效率上对比
RxBus 需要进行大量的二次开发,否则只能实现简单的事件传递,而EventBus只需简单了解一下API就能上手。如果一个订阅者需要注册多个事件的时候,需要多个Observable全局变量,这不是疯掉了吗,而EventBus已经实现了一个订阅者订阅多个事件,和一个事件对应多个订阅者。
4.)从功能完善上对比
上面三个对比也说明了,EventBus实现了事件的优先级,订阅事件运行的线程场景,以及粘性事件,这些在RxBus上面都需要进行二次实现。
总结:
基于RxJava实现简单的事件总线管理是可以的,但是个人觉得想要取代EventBus难免有点说过头了。所以如果项目中没有使用RxJava的话 还是采用EventBus比较靠谱。
Android消息传递之基于RxJava实现一个EventBus - RxBus的更多相关文章
- Android消息传递之EventBus 3.0使用详解
前言: 前面两篇不仅学习了子线程与UI主线程之间的通信方式,也学习了如何实现组件之间通信,基于前面的知识我们今天来分析一下EventBus是如何管理事件总线的,EventBus到底是不是最佳方案?学习 ...
- Android消息传递之EventBus 3.0
Android消息传递之EventBus 3.0使用详解 http://www.cnblogs.com/whoislcj/p/5595714.html EventBus 3.0进阶:源码及其设计模式 ...
- Android消息传递之Handler消息机制
前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...
- Android消息传递之组件间传递消息
前言: 上篇学习总结了Android通过Handler消息机制实现了工作线程与UI线程之间的通信,今天来学习一下如何实现组件之间的通信.本文依然是为学习EventBus做铺垫,有对比才能进步,今天主要 ...
- Android 使用RxJava实现一个发布/订阅事件总线
1.简单介绍 1.1.发布/订阅事件主要用于网络请求的回调. 事件总线可以使Android各组件之间的通信变得简单,而且可以解耦. 其实RxJava实现事件总线和EventBus比较类似,他们都依据与 ...
- 我的Android进阶之旅------>RxJava学习资料汇总
在响应式编程中,应该牢记以下两点: everything is a stream(一切皆流) don't break the chain(不要打断链式结构) 记住,可观测序列就像一条河,它们是流动的. ...
- 【腾讯Bugly干货分享】基于RxJava的一种MVP实现
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57bfef673c1174283d60bac0 Dev Club 是一个交流移动 ...
- 给 Android 开发人员的 RxJava 具体解释
鉴于 RxJava 眼下这样的既火爆又神奇的现状,而我又在一年的使用过程中对 RxJava 有了一些理解,我决定写下这篇文章来对 RxJava 做一个相对具体的.针对 Android 开发人员的介绍. ...
- 看eShopOnContainers学一个EventBus
最近在看微软eShopOnContainers 项目,看到EventBus觉得不错,和大家分享一下 看完此文你将获得什么? eShop中是如何设计事件总线的 实现一个InMemory事件总线eShop ...
随机推荐
- 透过WinDBG的视角看String
摘要 : 最近在博客园里面看到有人在讨论 C# String的一些特性. 大部分情况下是从CODING的角度来讨论String. 本人觉得非常好奇, 在运行时态, String是如何与这些特性联系上的 ...
- Emoji选项列表
一.需要的前提文件 从网上下载Emoji的表情包,当然是png的图片,因为WPF不支持彩色的Emoji,所以,做列表的时候,需要用图片. 随着压缩包一起的还有一个Emoji.xml文件,文件的层级结构 ...
- Android和JavaScript相互调用的方法
转载地址:http://www.jb51.net/article/77206.htm 这篇文章主要介绍了Android和JavaScript相互调用的方法,实例分析了Android的WebView执行 ...
- 用FSM一键制作逐帧动画雪碧图 Vue2 + webpack
因为工作需要要将五六十张逐帧图拼成雪碧图,网上想找到一件制作工具半天没有找到,就自己用canvas写了一个. 写成之后就再没有什么机会使用了,因此希望有人使用的时候如果遇到bug了能及时反馈给我. 最 ...
- 用MongoDB分析合肥餐饮业
看了<从数据角度解析福州美食>后难免心痒,动了要分析合肥餐饮业的念头,因此特地写了Node.js爬虫爬取了合肥的大众点评数据.分析数据库我并没有采用MySQL而是用的MongoDB,是因为 ...
- C#开发微信门户及应用(39)--使用微信JSSDK实现签到的功能
随着微信开逐步开放更多JSSDK的接口,我们可以利用自定义网页的方式来调用更多微信的接口,实现我们更加丰富的界面功能和效果,例如我们可以在页面中调用各种手机的硬件来获取信息,如摄像头拍照,GPS信息. ...
- Visual Studio Code——Angular2 Hello World 之 2.0
最近看到一篇用Visual Studio Code开发Angular2的文章,也是一篇入门教程,地址为:使用Visual Studio Code開發Angular 2專案.这里按部就班的做了一遍,感觉 ...
- Android 微信第三方登录(个人笔记)
今天在写微信登录,花了半天时间搞定.然后写下自己的笔记,希望帮助更多的人...欢迎各位指教. 微信授权登录,官方说的不是很清楚.所以导致有一部分的坑. 微信注册应用平台的应用签名,下载 微信签名生成工 ...
- sqlServer去除字符串空格
说起去除字符串首尾空格大家肯定第一个想到trim()函数,不过在sqlserver中是没有这个函数的,却而代之的是ltrim()和rtrim()两个函数.看到名字所有人都 知道做什么用的了,ltrim ...
- java 泛型
1.Student stu =tool.getObj();右边得到的是Object类型,需要向下转型,强转换. 2. 3. 4.泛型方法不能被静态修饰这样写 5.如果想定义定义静态泛型方法,只能这样写 ...