android rxbus 一个页面监听,Android RxBus的使用

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272598.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AngularJS $q

updatePushIdfunction($q,pushid) { var d$q.defer(); var data {pushid:pushid}; server.api("/updateRId",data).success(function(res){ if(res.resultcode1){ d.resolve(更新成功.);…

C# 如何转换生成长整型的时间

这个数字字符串就是我们平常所说的时间戳。什么是时间戳&#xff1f;时间戳&#xff08;timestamp&#xff09;&#xff0c;通常是一个字符序列&#xff0c;唯一地标识某一刻的时间。时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至…

html自动滑动轮播代码,html+css+js 实现自动滑动轮播图

轮播图*{margin: 0 auto;padding: 0;list-style: none; //去圆点}.one {width: 1200px;height:350px;margin: 0 auto;overflow: hidden; //设定好的宽度多余的进行隐藏}.one ul{width: 3600px;position: relative;}.one ul li{float: left; //图片浮动}.two ul li { …

程序员必定会爱上的10款软件

目录 第一款&#xff1a;TrueCrypt 第二款&#xff1a;Soureinsight 第三款&#xff1a;Sublime 第四款&#xff1a;Mindmanager 第五款&#xff1a;MarkdownPad 第六款&#xff1a;Beyond compare 第七款&#xff1a;Vim 第八款&#xff1a;Wireshark 第九款&#xff1a;Fiddl…

html定义字体纵向对齐,HTML5 Canvas的文本如何实现垂直对齐

垂直对齐&#xff0c;使用CSS很容易实现&#xff0c;如果想在HTML5 Canvas中实现垂直对齐&#xff0c;如何设置呢&#xff0c;这就是今天要分享的笔记。HTML画布垂直对齐的文本&#xff0c;我们可以使用的textBaseline在画布范围内的属性值。textBaseline可以设置以下值之一 &a…

深度学习方法:受限玻尔兹曼机RBM(三)模型求解,Gibbs sampling

欢迎转载&#xff0c;转载请注明&#xff1a;本文出自Bin的专栏blog.csdn.net/xbinworld。 技术交流QQ群&#xff1a;433250724&#xff0c;欢迎对算法、技术、应用感兴趣的同学加入。 接下来重点讲一下RBM模型求解方法&#xff0c;其实用的依然是梯度优化方法&#xff0c;但是…

推荐一款PC端的远程软件-Remote Utilities

远程控制软件非常之多&#xff0c;但小编自己用过的就那么3个&#xff1a;teamviewer&#xff1a;在家远程办公时基本上都靠它连回公司的电脑&#xff0c;速度快、稳定、不需要公网IP。vnc&#xff1a;要开启vpn才能连回公司的网络&#xff0c;速度够快。系统自带远程桌面&…

原生js追加html代码,原生js实现给指定元素的后面追加内容

复制代码 代码如下:var header1 document.getElementById("header");var p document.createElement("p"); // 创建一个元素节点insertAfter(p,header1); // 因为js没有直接追加到指定元素后面的方法 所以要自己创建一个方法function insertAfter( newEle…

这些才是Win10真正好用之处:瞬对Win7无爱

自从将家里的笔电、台式机全部升级到Win10之后&#xff0c;小编可是切切实实感受到了它的强大&#xff0c;非常多的改进、非常多人性化的设计。和之前的测试版不同&#xff0c;作为主力系统后自然要匹配日常的工作。很多设置、操作也要顺应以前的使用习惯。经过这几天折腾&…

html5 保存 搜索历史,html5 – 如何有效处理Dart中的浏览器历史记录(即后退按钮)?...

HTML5定义了用于操作历史记录的新API,允许您在不重新加载窗口的情况下更改位置.有一篇关于Dive Into HTML5的精彩文章,展示了如何使用历史API在单页面应用中模拟多页面导航.它很容易翻译成Dart.在带导航的单页应用程序中,我通常设置客户端代码的方式类似于在服务器上设置RoR或D…

多个DataSet数据合并

DataSet ds myIAppSet.GetHomeHottestList(siteID, 0, time); DataSet ds1 myIAppSet.GetHomeHottestList(siteID, 1, time);if (ds1 ! null && ds1.Tables[0].Rows.Count > 0){ds.Merge(ds1);} Merge方法&#xff0c;用于DataSet、DataTable&#xff0c;多个字段…

math.js:灵活强大的JavaScript数学库

最近为期权开发一些基本技术指标&#xff0c;用到一些C的数学库&#xff0c;刚好看到JavaScript的math.js库&#xff0c;这里对math.js做一下简单介绍。一、什么是math.jsmath.js是一个广泛应用于JavaScript 和 Node.js的数学库&#xff0c;它的特点是灵活表达式解析器&#xf…

html的闪烁字,HTML最简单的文字闪烁代码

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼Titlekeyframes blink{0%{opacity: 1;}50%{opacity: 1;}50.01%{opacity: 0;}100%{opacity: 0;}}-webkit-keyframes blink {0% { opacity: 1; }50% { opacity: 1; }50.01% { opacity: 0; }100% { opacity: 0; }}-moz-keyframes blin…

video和dvd audio区别:

VIDEO 是视频&#xff0c;AUDIO是音频。DVD- Audio 是目前流行的DVD光碟格式的一种扩展&#xff0c;区别在于它能够传输先前所有音频载体格式无法携带的全新标准的高质量音频数据。最引人注目的特点是它多声道音频的能力。转载于:https://www.cnblogs.com/zjqqqq/p/5060931.htm…

Win10非常好用的6个使用技巧

很多人已经用上了Win10系统&#xff0c;为了提高使用效率掌握使用技巧尤为重要&#xff0c;今天我为大家分享win10的6个使用技巧。第一个&#xff1a;快速查找文件&#xff08;win键E&#xff09;想要打开某个文件&#xff0c;直接使用这个快捷键就可以打开资源管理器&#xff…

servlet html登录,Servlet实现用户登录

1、登录过程分析&#xff1a;通过表单收集用户的数据&#xff0c;Servlet通过request对象获得用户提交的数据&#xff0c;服务器还需要从数据库中通过sql语句查询有没有表单提交的数据中的用户。有则登录成功&#xff0c;否则&#xff0c;登录失败。2、工程结构&#xff1a;3、…

HTML5拖放API

HTML5拖放API 拖放事件 HTML5拖放API 拖放事件事件提供了拖放可以控制几乎所有方面的拖放操作。棘手的部分是确定每个事件触发&#xff1a;在拖项目火&#xff1b;别人火下降的目标。 拖动项时&#xff0c;以下事件&#xff08;按照这个顺序&#xff09;&#xff1a;拖曳开始拖…

C#easyui combotree 设置节点折叠

树实体public class Combotree{public string id { get; set; }public string text { get; set; }public string state { get; set; }public List<Combotree> children { get; set; }} 只需要在初始化数据的时候给state 设置为 closed注意&#xff1a;不要在最后一级节点…

用于大型的科学计算的计算机,科学计算器广泛适用于大、中、小学生、教师、科研人员及其他各界...

科学计算器广泛适用于大、中、小学生、教师、科研人员及其他各界人士。相关句子1、机器人广泛应用于弧焊&#xff0c;点焊&#xff0c;涂胶&#xff0c;切割&#xff0c;搬运&#xff0c;码垛&#xff0c;喷漆&#xff0c;科研及教学。3、可以满足大学本科和研究生有关实验课教…

C#中AssemblyInfo.cs文件详解

1、.Net工程的Properties文件夹下自动生成一个名为AssemblyInfo.cs的文件&#xff0c;一般情况下我们很少直接改动该文件。但我们实际上通过另一个形式操作该文件。那就是通过在鼠标右键点击项目的属性进入“应用程序”->“程序集信息”&#xff0c;然后修改信息。2、通过特…