前言:

上篇文章学习了Android事件总线管理开源框架EventBus,EventBus的出现大大降低了开发成本以及开发难度,今天我们就利用目前大红大紫的RxJava来实现一下类似EventBus事件总线管理,现在很多人都在说用这种方式来替代EventBus,今天我们从开发效率,开发难度等维度来分析一下到底能不能取代EventBus? 先回顾一下什么是EventBus?请看这篇文章Android消息传递之EventBus 3.0使用详解(三)

消息传递相关文章地址:

需求:

虽然软件工程师就害怕听见“需求”这两个字,但是一切功能来源于需求,我们要基于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的更多相关文章

  1. Android消息传递之EventBus 3.0使用详解

    前言: 前面两篇不仅学习了子线程与UI主线程之间的通信方式,也学习了如何实现组件之间通信,基于前面的知识我们今天来分析一下EventBus是如何管理事件总线的,EventBus到底是不是最佳方案?学习 ...

  2. Android消息传递之EventBus 3.0

    Android消息传递之EventBus 3.0使用详解 http://www.cnblogs.com/whoislcj/p/5595714.html EventBus 3.0进阶:源码及其设计模式 ...

  3. Android消息传递之Handler消息机制

    前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...

  4. Android消息传递之组件间传递消息

    前言: 上篇学习总结了Android通过Handler消息机制实现了工作线程与UI线程之间的通信,今天来学习一下如何实现组件之间的通信.本文依然是为学习EventBus做铺垫,有对比才能进步,今天主要 ...

  5. Android 使用RxJava实现一个发布/订阅事件总线

    1.简单介绍 1.1.发布/订阅事件主要用于网络请求的回调. 事件总线可以使Android各组件之间的通信变得简单,而且可以解耦. 其实RxJava实现事件总线和EventBus比较类似,他们都依据与 ...

  6. 我的Android进阶之旅------>RxJava学习资料汇总

    在响应式编程中,应该牢记以下两点: everything is a stream(一切皆流) don't break the chain(不要打断链式结构) 记住,可观测序列就像一条河,它们是流动的. ...

  7. 【腾讯Bugly干货分享】基于RxJava的一种MVP实现

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57bfef673c1174283d60bac0 Dev Club 是一个交流移动 ...

  8. 给 Android 开发人员的 RxJava 具体解释

    鉴于 RxJava 眼下这样的既火爆又神奇的现状,而我又在一年的使用过程中对 RxJava 有了一些理解,我决定写下这篇文章来对 RxJava 做一个相对具体的.针对 Android 开发人员的介绍. ...

  9. 看eShopOnContainers学一个EventBus

    最近在看微软eShopOnContainers 项目,看到EventBus觉得不错,和大家分享一下 看完此文你将获得什么? eShop中是如何设计事件总线的 实现一个InMemory事件总线eShop ...

随机推荐

  1. Logstash实践: 分布式系统的日志监控

    文/赵杰 2015.11.04 1. 前言 服务端日志你有多重视? 我们没有日志 有日志,但基本不去控制需要输出的内容 经常微调日志,只输出我们想看和有用的 经常监控日志,一方面帮助日志微调,一方面及 ...

  2. SQL Server内存遭遇操作系统进程压榨案例

    场景: 最近一台DB服务器偶尔出现CPU报警,我的邮件报警阈(请读yù)值设置的是15%,开始时没当回事,以为是有什么统计类的查询,后来越来越频繁. 探索: 我决定来查一下,究竟是什么在作怪,我排查的 ...

  3. nodejs之get/post请求的几种方式

    最近一段时间在学习前端向服务器发送数据和请求数据,下面总结了一下向服务器发送请求用get和post的几种不同请求方式: 1.用form表单的方法:(1)get方法 前端代码: <form act ...

  4. C#基础篇 - 正则表达式入门

    1.基本概念 正则表达式(Regular Expression)就是用事先定义好的一些特定字符(元字符)或普通字符.及这些字符的组合,组成一个“规则字符串”,这个“规则字符串”用来判断我们给定的字符串 ...

  5. 13、零配置Struts2开发

    Convention 插件 从 Struts 2.1 开始, Struts 可以使用 Convention 插件来支持零配置: Convention 插件完全抛弃配置信息, 不仅不需要使用 strut ...

  6. Go web开发初探

    2017年的第一篇博客,也是第一次写博客,写的不好,请各位见谅. 本人之前一直学习java.java web,最近开始学习Go语言,所以也想了解一下Go语言中web的开发方式以及运行机制. 在< ...

  7. C#与C++通信

    # C#与C++相互发送消息 # ## C#端: ## namespace CshapMessage { /// /// MainWindow.xaml 的交互逻辑 /// public partia ...

  8. JavaScript学习笔记(三)——this、原型、javascript面向对象

    一.this 在JavaScript中this表示:谁调用它,this就是谁. JavaScript是由对象组成的,一切皆为对象,万物皆为对象.this是一个动态的对象,根据调用的对象不同而发生变化, ...

  9. 拦截UIViewController的popViewController事件

    实现拦截UIViewController的pop操作有两种方式: 自定义实现返回按钮,即设置UIBarButtonItem来实现自定义的返回操作. 创建UINavigatonController的Ca ...

  10. T-SQL字符串相加之后被截断的那点事

    本文出处:http://www.cnblogs.com/wy123/p/6217772.html 字符串自身相加, 虽然赋值给了varchar(max)类型的变量,在某些特殊情况下仍然会被“截断”,这 ...