RxBus的核心功能是基于Rxjava的,在RxJava中有个Subject类,它继承Observable类,同时实现了Observer接口,因此Subject可以同时担当订阅者和被订阅者的角色,这里我们使用Subject的子类PublishSubject来创建一个Subject对象(PublishSubject只有被订阅后才会把接收到的事件立刻发送给订阅者),在需要接收事件的地方,订阅该Subject对象,之后如果Subject对象接收到事件,则会发射给该订阅者,此时Subject对象充当被订阅者的角色。完成了订阅,在需要发送事件的地方将事件发送给之前被订阅的Subject对象,则此时Subject对象做为订阅者接收事件,然后会立刻将事件转发给订阅该Subject对象的订阅者,以便订阅者处理相应事件,到这里就完成了事件的发送与处理。最后就是取消订阅的操作了,Rxjava中,订阅操作会返回一个Subscription对象,以便在合适的时机取消订阅,防止内存泄漏,如果一个类产生多个Subscription对象,我们可以用一个CompositeSubscription存储起来,以进行批量的取消订阅。

首先添加类库

// RxAndroid

compile 'io.reactivex:rxandroid:1.2.1'

// RxJava

compile 'io.reactivex:rxjava:1.2.4'

1、接下来结合实现代码再做进一步的解释:

package com.example.rxbus;

import java.util.HashMap;

import rx.Observable;

import rx.Subscription;

import rx.android.schedulers.AndroidSchedulers;

import rx.functions.Action1;

import rx.schedulers.Schedulers;

import rx.subjects.PublishSubject;

import rx.subjects.SerializedSubject;

import rx.subscriptions.CompositeSubscription;

/**

* @author: lijuan

* @description:

* @date: 2017-06-07

* @time: 17:24

*/

public class RxBus {

private static volatile RxBus mInstance;

private SerializedSubject mSubject;

private HashMap mSubscriptionMap;

private RxBus() {

mSubject = new SerializedSubject<>(PublishSubject.create());

}

public static RxBus getInstance() {

if (mInstance == null) {

synchronized (RxBus.class) {

if (mInstance == null) {

mInstance = new RxBus();

}

}

}

return mInstance;

}

/**

* 发送事件

*

* @param o

*/

public void post(Object o) {

mSubject.onNext(o);

}

/**

* 返回指定类型的Observable实例

*

* @param type

* @param

* @return

*/

public Observable tObservable(final Class type) {

return mSubject.ofType(type);

}

/**

* 是否已有观察者订阅

*

* @return

*/

public boolean hasObservers() {

return mSubject.hasObservers();

}

/**

* 一个默认的订阅方法

*

* @param type

* @param next

* @param error

* @param

* @return

*/

public Subscription doSubscribe(Class type, Action1 next, Action1 error) {

return tObservable(type)

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(next, error);

}

/**

* 保存订阅后的subscription

*

* @param o

* @param subscription

*/

public void addSubscription(Object o, Subscription subscription) {

if (mSubscriptionMap == null) {

mSubscriptionMap = new HashMap<>();

}

String key = o.getClass().getName();

if (mSubscriptionMap.get(key) != null) {

mSubscriptionMap.get(key).add(subscription);

} else {

CompositeSubscription compositeSubscription = new CompositeSubscription();

compositeSubscription.add(subscription);

mSubscriptionMap.put(key, compositeSubscription);

}

}

/**

* 取消订阅

*

* @param o

*/

public void unSubscribe(Object o) {

if (mSubscriptionMap == null) {

return;

}

String key = o.getClass().getName();

if (!mSubscriptionMap.containsKey(key)) {

return;

}

if (mSubscriptionMap.get(key) != null) {

mSubscriptionMap.get(key).unsubscribe();

}

mSubscriptionMap.remove(key);

}

}

先看一下这个私有的构造函数:

private RxBus() {

mSubject = new SerializedSubject<>(PublishSubject.create());

}

由于Subject类是非线程安全的,所以我们通过它的子类SerializedSubject将PublishSubject转换成一个线程安全的Subject对象。之后可通过单例方法getInstance()进行RxBus的初始化。

在toObservable()根据事件类型,通过mSubject.ofType(type);得到一个Observable对象,让其它订阅者来订阅。其实ofType()方法,会过滤掉不符合条件的事件类型,然后将满足条件的事件类型通过cast()方法,转换成对应类型的Observable对象,这点可通过源码查看。

同时封装了一个简单的订阅方法doSubscribe(),只需要传入事件类型,相应的回调即可。其实可以根据需求在RxBus中扩展满足自己需求的doSubscribe()方法,来简化使用时的代码逻辑。

在需要发送事件的地方调用post()方法,它间接的通过mSubject.onNext(o);将事件发送给订阅者。

同时RxBus提供了addSubscription()、unSubscribe()方法,分别来保存订阅时返回的Subscription对象,以及取消订阅。

接下我们在具体的场景中测试一下:

1、我们在Activity的onCreate()方法中进行进行订阅操作:

public static final int SEND = 0x131;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

doSubscribe();

}

/**

* 订阅事件监听

*/

public void doSubscribe() {

Subscription subscription = RxBus.getInstance()

.tObservable(NewsModel.class)

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Action1() {

@Override

public void call(NewsModel model) {

switch (model.getStatus()) {

case SEND:

Log.e("rxbus", model.getMsg());

break;

default:

break;

}

}

});

RxBus.getInstance().addSubscription(this, subscription);

}

可以看到我们设定事件类型为NewsModel实体类,当然我们可以设定事件类型为为String或者Integer,并且Subscriber的回调发生在主线程,同时保存了Subscription对象。

2、现在通过一个Button发送事件:

RxBus.getInstance().post(new NewsModel(SEND, "发送一条信息"));

3、最后不要忘了在onDestory()中对广播进行取消注册,以及取消订阅

protected void onDestroy() {

super.onDestroy();

RxBus.getInstance().unSubscribe(this);

}

其它场景有兴趣的可自行测试!本篇文章就这样子啦,存在总结不到位的地方还望指导,感谢_

参考资料:Android 用RxJava模拟一个EventBus ———RxBus

android rxbus 一个页面监听,Android RxBus的使用相关推荐

  1. android u盘挂载监听,Android SD卡及U盘插拔状态监听及内容读取

    本篇是通过系统方法来对sd卡及U盘插拔监听及数据获取,Android盒子端开发,有系统权限,当然,这个比较简单,知道具体方法,可以通过反射来实现. 先贴上效果图: 获取外置存储设备并监听插拔状态 获取 ...

  2. android 后台键盘按键监听,android键盘的监听

    android 键盘监听 从知乎上看到的一种解决方案,目前还没发现有什么坑. public class SoftKeyBroadManager implements ViewTreeObserver. ...

  3. android按钮怎么事件监听,android 通过监听edittext实现button的点击事件

    如果你没有接第三方的输入设备,那么点击按钮只需找到你的button然后:button.performClick(); 就可以了 那么如果你用到第三方输入法,有些时候监听就没有这么好使了: 以下场景为: ...

  4. android 摇一摇监听,Android摇一摇功能实现(摇一摇监听)

    近期项目中要求增加摇一摇功能,搜了相关帖子,自己整理一套代码,发个博客保留一份. 解析:Android中摇一摇主要通过[SensorManager]实现,想了解可以查一下. 上期的不够完善 更新了一下 ...

  5. android 转场动画 监听,Android 中的转场动画及兼容处理

    Android 中的动画有很多,除了在一个界面上使用帧动画.属性动画将一个或多个 View 进行动画处理以外,还可以用于两个界面之间过渡.跳转.在 Android 5.0 之前,我们已经有了 over ...

  6. android定义两个监听,Android中的2个手指旋转手势监听器

    我试图找出使图像旋转的最佳方法,用户的手指向左或向右拖动,以及旋转角度. float x1 = lastEvent[0] - lastEvent[1]; float y1 = lastEvent[2] ...

  7. android 回退函数,详解React Native监听Android回退按键与程序化退出应用

    详解React Native监听Android回退按键与程序化退出应用 发布时间:2020-09-29 09:25:52 来源:脚本之家 阅读:137 作者:lqh 详解React Native监听A ...

  8. Android学习按键事件监听与Command模式

    Android学习按键事件监听与Command模式 - Dufresne - 博客园 Android学习按键事件监听与Command模式 一 Command模式 意图: 将一个请求封装为一个对象,从而 ...

  9. android列表项点击事件,Android 开发 tips(2):监听 Listview 列表项点击事件

    Android 开发 tips(2):监听 Listview 列表项点击事件 (这篇和上篇本来是应该一起写的,但是太过冗长,附链接:[SimpleAdapter 在 Listview 中的应用] ht ...

最新文章

  1. ISME:西农沈锡辉+韦革宏+王瑶揭示细菌铁获取和外膜囊泡招募新机制
  2. 浏览器内存不足导致页面崩溃_深度精读:浏览器渲染原理 [8000字图文并茂]
  3. 冒泡、选择、插入排序算法
  4. linux命令查询邮件发送状态,Linux发邮件之mail命令详解
  5. 1-4 数组元素的区间删除 (20 分)
  6. python 可视化大屏幕_如何用python搭建可视化看板?
  7. bzoj 1704: [Usaco2007 Mar]Face The Right Way 自动转身机
  8. 基于jQuery8款超赞的评分插件
  9. AI 时代,程序员从小白到小牛的发展攻略丨今晚直播送机械键盘!
  10. linux离线安装docx包
  11. geforce experience出现错误尝试重启PC
  12. Object-Oriented Programming Summary Ⅲ
  13. 《C语言入门》猜数字小游戏代码实现
  14. DevEco Studio JS sdk下载问题
  15. DY__ac_signature
  16. linux之bound网络配置
  17. ubuntu16.04 笔记本 安装双显卡驱动GTX960M 可快捷切换
  18. 序列化Serializable接口
  19. apt-get -y install中的-y是什么意思?
  20. 用批处理在桌面上创建快捷方式

热门文章

  1. windows下python视频加速调节_Windows下python+ffmpeg实现批量提取、切割视频中的音频...
  2. 第5章 Python 数字图像处理(DIP) - 图像复原与重建12 - 空间滤波 - 使用频率域滤波降低周期噪声 - 陷波滤波、最优陷波滤波
  3. 第2章 Python 数字图像处理(DIP) --数字图像基础4 -- 像素间的一些基本关系 - 邻域 - 距离测试
  4. Python中的高级数据结构
  5. 【Leetcode】【Longest Palindromic Substring】【最长回文子串】【C++】
  6. (转)java内部类详解
  7. OAuth2.0学习(2-1)Spring Security OAuth2.0 开发指南
  8. iOS十进制切割格式转换
  9. Docker学习笔记1 :镜像制作
  10. (原创)RHEL/CentOS 5.x使用yum快速安装MySQL 5.5.x