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 vitamio封装,Android视频框架Vitamio构建自己的通用播放器

    Vitamio是Android和iOS平台上的全方位多媒体开发框架,完全支持硬件解码和GPU渲染. Vitamio功能强大手机上的万能播放器,可以平滑播放720P或1080P HD MKV,FLV手机 ...

  2. android 九宫格封装,Android 九宫格的实现方法

    1.xml代码: android:orientation="vertical" android:layout_width="fill_parent" andro ...

  3. android 九宫格封装,Android 九宫格布局

    演示 image 需求 满足0-9个图的适配 图数量 演示 1 image 2 image 3 image 4 image 5 image 6 image 7 image 8 image 9 imag ...

  4. android动画封装,Android属性动画封装,快速构建动画

    Android实现动画效果的方式主要有帧动画.补间动画.属性动画.关于安桌动画的基础知识可以查看这篇文章Android属性动画完全解析 这里我要讲的是如何快速构建出一个动画效果,如下图: 如果我们用属 ...

  5. android websocket封装,Android WebSocket 方案选型OkHttp

    目前Android WebSocket 框架 主要包括: SocketIO Java-WebSocket OkHttp WebSocket 一开始我首选的是采用SocketIO方案,因为考虑该方案封装 ...

  6. android适配器封装,Android万能适配器(一)封装ViewHolder

    封装 ViewHolder 简单分析ViewHolder封装.ViewHolder内部正常是保存每个页面控件的索引,那么封装时候我们可以使用容器把每个Item布局中的所有控件存储到这个容器里面,每次使 ...

  7. android动画封装,Android开场动画类完整实现代码

    本文所述实例为在android中开起开场动画类,已封装好,进行android开发的朋友可使用.在这个类中,你可以:设置开场动画的图片资源.返回下一个要启动的Activity.显示开场动画.执行耗时的操 ...

  8. android 九宫格封装,Android 实现九宫格、点击图片放大全屏浏览等

    live_icon.jpg 1370473-587d9058f76372fb.gif 说说我的实现思路: 逐渐掌握了Android开发套路,是时候自己去封装一些东西了.网上看了一些例子,感觉不是我想要 ...

  9. android 多线程封装,Android线程池封装库

    目录介绍 1.遇到的问题和需求 1.1 遇到的问题有哪些 1.2 遇到的需求 1.3 多线程通过实现Runnable弊端 1.4 为什么要用线程池 2.封装库具有的功能 2.1 常用的功能 3.封装库 ...

  10. android 多线程封装,Android 线程池的封装

    GlobalThreadPools.java: /** * 全局使用的线程池 */ public class GlobalThreadPools { private static String TAG ...

最新文章

  1. ios 关于block传值报错
  2. 硬核!手写一个优先队列
  3. 用scikit-learn和pandas学习线性回归
  4. Chrome上出现的问题
  5. JavaScript面向对象实现
  6. 品运维自动化之cobbler的安装序
  7. spring data mongodb CURD
  8. 玲珑学院 1138 - 震惊,99%+的中国人都会算错的问题
  9. matlab 中文件夹下图像的批处理
  10. Codeforces Round 258(Div. 2)
  11. win7开启不了Aero
  12. headers信息修改
  13. android学习之展示图片资源
  14. 大数据分析-考试复习
  15. 儿子跟妈妈关系不好怎么办?这里有解决办法!
  16. Java获取URL对应的资源
  17. c语言设计一个学生成绩管理系统,用C语言设计的学生成绩管理系统1.doc
  18. 贸然用string比较的后果
  19. 【现代货币银行学】信用和利率(上)
  20. FEKO仿真涂覆目标时的参数设置

热门文章

  1. 连接共享打印机0x0000011b win10
  2. 好用的滚动式截图工具picpick
  3. Exploring Simple Siamese Representation Learning
  4. Struts1.x使用入门
  5. 地图下面的标尺是什么意思_【一点资讯】地图的主要类型有哪些? 何谓地图比例尺? 什么是地图注记? www.yidianzixun.com...
  6. 联通ip电视html1连不上,刷华硕固件看联通IPTV和上网两不误
  7. 事业单位资产管理系统破解资产管理难题,实现账、卡、物、地、人相符
  8. 中医药天池大数据竞赛——中医文献问题生成挑战(三)
  9. 中国县级和以下行政区编码,2013年,sql文件
  10. 台式计算机如何双屏显示,电脑怎么分屏?|台式电脑双显示器连接方法