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 ...
随机推荐
- ArcGIS 10.0紧凑型切片读写方法
首先介绍一下ArcGIS10.0的缓存机制: 切片方案 切片方案包括缓存的比例级别.切片尺寸和切片原点.这些属性定义缓存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要.图像格式和抗锯齿等 ...
- 透过WinDBG的视角看String
摘要 : 最近在博客园里面看到有人在讨论 C# String的一些特性. 大部分情况下是从CODING的角度来讨论String. 本人觉得非常好奇, 在运行时态, String是如何与这些特性联系上的 ...
- Android Ormlite 学习笔记2 -- 主外键关系
以上一篇为例子,进行主外键的查询 定义Users.java 和 Role.java Users -- Role 关系为:1对1 即父表关系 Role -- Users 关系为:1对多 即子表关系 下面 ...
- SDWebImage源码解读_之SDWebImageDecoder
第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...
- Ajax使用WCF实现小票pos机打印源码
通过ajax跨域方式调用WCF服务,实现小票pos机的打印,源码提供web方式,客户端方式测试,服务驻留右侧底部任务栏,可控制服务开启暂停,用户可自定义小票打印模板,配合零售录入. qq 22945 ...
- Android之使用文件进行IPC
一.文件进行IPC介绍 共享文件也是一种不错的进程间通信方式,两个进程通过读/写同一个文件来交换数据.在Windows上,一个文件如果被加了排斥锁将会导致其他线程无法对其进行访问,包括读写,而由于An ...
- Atitit 管理原理与实践attilax总结
Atitit 管理原理与实践attilax总结 1. 管理学分类1 2. 我要学的管理学科2 3. 管理学原理2 4. 管理心理学2 5. 现代管理理论与方法2 6. <领导科学与艺术4 7. ...
- APP漏洞扫描用地址空间随机化
APP漏洞扫描用地址空间随机化 前言 我们在前文<APP漏洞扫描器之本地拒绝服务检测详解>了解到阿里聚安全漏洞扫描器有一项静态分析加动态模糊测试的方法来检测的功能,并详细的介绍了它在针对本 ...
- .NET面试题系列[7] - 委托与事件
委托和事件 委托在C#中具有无比重要的地位. C#中的委托可以说俯拾即是,从LINQ中的lambda表达式到(包括但不限于)winform,wpf中的各种事件都有着委托的身影.C#中如果没有了事件,那 ...
- [译]DbContext API中使用SqlQuery和ExecuteSqlCommand获取存储过程的输入输出参数
水平有限,欢迎指正.原文:http://blogs.msdn.com/b/diego/archive/2012/01/10/how-to-execute-stored-procedures-sqlqu ...