[Android]基于RxJava、RxAndroid的EventBus实现
以下内容为原创,欢迎转载,转载请注明
来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4578699.html
Github:https://github.com/wangjiegulu/RxAndroidEventsSample
EventBus的作用是发布/订阅事件总线,因为项目中用到RxJava、RxAndroid,所以完全可以使用RxJava、RxAndroid来实现EventBus。
1. 编写RxBus,用于存储所有事件Subjects。
事件是传递的最小单位,可以把任何类作为一个事件。
RxBus代码如下:
/**
* Author: wangjie
* Email: tiantian.china.2@gmail.com
* Date: 6/11/15.
*/
public class RxBus {
private static final String TAG = RxBus.class.getSimpleName();
private static RxBus instance;
public static boolean DEBUG = false; public static synchronized RxBus get() {
if (null == instance) {
instance = new RxBus();
}
return instance;
} private RxBus() {
} private ConcurrentHashMap<Object, List<Subject>> subjectMapper = new ConcurrentHashMap<>(); @SuppressWarnings("unchecked")
public <T> Observable<T> register(@NonNull Object tag, @NonNull Class<T> clazz) {
List<Subject> subjectList = subjectMapper.get(tag);
if (null == subjectList) {
subjectList = new ArrayList<>();
subjectMapper.put(tag, subjectList);
} Subject<T, T> subject;
subjectList.add(subject = PublishSubject.create());
if (DEBUG) Log.d(TAG, "[register]subjectMapper: " + subjectMapper);
return subject;
} public void unregister(@NonNull Object tag, @NonNull Observable observable) {
List<Subject> subjects = subjectMapper.get(tag);
if (null != subjects) {
subjects.remove((Subject) observable);
if (ABTextUtil.isEmpty(subjects)) {
subjectMapper.remove(tag);
}
} if (DEBUG) Log.d(TAG, "[unregister]subjectMapper: " + subjectMapper);
} public void post(@NonNull Object content) {
post(content.getClass().getName(), content);
} @SuppressWarnings("unchecked")
public void post(@NonNull Object tag, @NonNull Object content) {
List<Subject> subjectList = subjectMapper.get(tag); if (!ABTextUtil.isEmpty(subjectList)) {
for (Subject subject : subjectList) {
subject.onNext(content);
}
}
if (DEBUG) Log.d(TAG, "[send]subjectMapper: " + subjectMapper);
}
}
如上述代码,RxBus只提供了register、unregister、post三个方法。
这里又加入了一个tag的概念,也可以理解为channel,注册Subject、反注册Subject和post事件的时候都需要这个tag,只有tag一致才能正常接收到事件。
比如有一个事件类HelloEvent,这个事件的作用是接收到后toast一个提示“hello”,如果两个Activity都注册了这个HelloEvent事件,但是没有tag去限制,一旦post了一个helloEvent事件后,两个Activity都会收到这个事件,导致两个Activity都会toast。如果使用tag,post这个HelloEvent的时候可以设置这个tag,只有register时也使用了这个tag才会接收到这个event。
2. 在Present(如Activity的onCreate)中注册一个Observer(以下以发送一个String类型的事件为例)
Observable<String> addOb = RxBus.get()
.register("addFeedTag", String.class); addOb.observeOn(AndroidSchedulers.mainThread())
.subscribe(s -> {
// todo: Accept event and process here
});
如上,注册了一个String类型的事件,事件的tag是“addFeedTag”,用来增加一个Feed。使用RxAndroid在Action1中处理接收到的这个事件。
3. 在任何地方发送一个事件:
RxBus.get().post("addFeedTag", "hello RxBus!");
这里发送了一个tag为“addFeedTag”的String类型的事件。
4. 反注册Observer:
RxBus.get().unregister("addFeedTag", addOb);
注意:这里的Tag都为“addFeedTag”。
下面使用注解的方式更简单方便地使用RxBus(嗯-。-这里才是重点)。
首先来看下使用注解后的代码:
1. 注册Observer
这一步可以省略掉。
2. 发送一个事件(这里我们换一个事件:FeedItemClickEvent,我们定义这个事件是用来处理当Feed被点击后的事件)
RxBus.get().post(new FeedItemClickEvent().setPosition(position).setFeed(feed));
3. 接收事件,然后处理
@Accept
public void onPostAccept(Object tag, FeedItemClickEvent event) {
Logger.d(TAG, "onPostAccept event: " + event);
Feed feed = event.getFeed();
// 跳转到feed详情页面...
}
如上,这里只需要编写一个方法,加上Accept注解,然后在方法中进行事件处理即可。
注意:方法名可以任意
方法参数一:必须为Object类型的tag;
方法参数二,如果这个方法只接收一种事件,则写明具体的事件类型,如上;如果这个方法接收多种事件,则类型需要为Object。
4. 反注册Observer
这一步也可以省略掉。
接收多种事件:
@Accept(
acceptScheduler = AcceptScheduler.NEW_THREAD,
value = {
@AcceptType(tag = ActionEvent.CLOSE, clazz = String.class),
@AcceptType(tag = ActionEvent.BACK, clazz = String.class),
@AcceptType(tag = ActionEvent.EDIT, clazz = String.class),
@AcceptType(tag = ActionEvent.REFRESH, clazz = String.class)
}
)
public void onPostAccept(Object tag, Object actionEvent) {
Logger.d(TAG, "[ActionEvent]onPostAccept action event name: " + actionEvent);
// todo: Accept event and process here (in new thread)
}
这里@Accept注解中设置了acceptScheduler为AcceptScheduler.NEW_THREAD,指明方法运行在子线程中.
value中指明了接收的事件类型,这里表示这个方法接收4种类型的事件:CLOSE, BACK, EDIT, REFRESH.
注解解释:
@Accept注解
acceptScheduler: 指定被注解的方法运行的Scheduler。
value[]: AcceptType注解数组,用于指定接收事件的tag和class。
@AcceptType注解:
tag: 接收事件的tag
clazz: 接收事件的类型
AcceptScheduler:
详情见:rx.schedulers.Schedulers和rx.android.schedulers.AndroidSchedulers
如果设置的是AcceptScheduler.EXECUTOR或AcceptScheduler.HANDLER,则需要在Application中配置Executor和Handler:
/**
* Author: wangjie
* Email: tiantian.china.2@gmail.com
* Date: 6/15/15.
*/
public class MyApplication extends Application {
private Executor acceptExecutor = Executors.newCachedThreadPool();
private Handler handler = new Handler(Looper.getMainLooper()); @Override
public void onCreate() {
super.onCreate();
RxBus.DEBUG = true; DefaultAcceptConfiguration.getInstance().registerAcceptConfiguration(new DefaultAcceptConfiguration.OnDefaultAcceptConfiguration() {
@Override
public Executor applyAcceptExecutor() {
return acceptExecutor;
} @Override
public Handler applyAcceptHandler() {
return handler;
}
});
}
}
因为需要对Accept和AcceptType注解的解析,所以项目的BaseActivity需要使用AIAppCompatActivity,然后实现parserMethodAnnotations()方法,使用RxBusAnnotationManager对注解进行解析。
参考:http://nerds.weddingpartyapp.com/tech/2014/12/24/implementing-an-event-bus-with-rxjava-rxbus/
[Android]基于RxJava、RxAndroid的EventBus实现的更多相关文章
- Android消息传递之基于RxJava实现一个EventBus - RxBus
前言: 上篇文章学习了Android事件总线管理开源框架EventBus,EventBus的出现大大降低了开发成本以及开发难度,今天我们就利用目前大红大紫的RxJava来实现一下类似EventBus事 ...
- Android 使用RxJava实现一个发布/订阅事件总线
1.简单介绍 1.1.发布/订阅事件主要用于网络请求的回调. 事件总线可以使Android各组件之间的通信变得简单,而且可以解耦. 其实RxJava实现事件总线和EventBus比较类似,他们都依据与 ...
- Android 基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器aaa
MDPlayer万能播放器 MDPlayer,基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器,可以播 ...
- Android RxJava/RxAndroid结合Retrofit使用
概述 RxJava是一个在 Java VM 上使用可观測的序列来组成异步的.基于事件的程序的库.更重要的是:使用RxJava在代码逻辑上会非常简洁明了,尤其是在复杂的逻辑上.告别迷之缩进. RxAnd ...
- 78. Android之 RxJava 详解
转载:http://gank.io/post/560e15be2dca930e00da1083 前言 我从去年开始使用 RxJava ,到现在一年多了.今年加入了 Flipboard 后,看到 Fli ...
- 【腾讯Bugly干货分享】基于RxJava的一种MVP实现
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57bfef673c1174283d60bac0 Dev Club 是一个交流移动 ...
- RxJava RxAndroid【简介】
资源 RxJava:https://github.com/ReactiveX/RxJava RxAndroid :https://github.com/ReactiveX/RxAndroid 官网:h ...
- Android使用RxJava+Retrofit2+Okhttp+MVP练习的APP
Android使用RxJava+Retrofit2+Okhttp+MVP练习的APP 项目截图 这是我的目录结构 五步使用RxJava+Retrofit2+Okhttp+RxCache 第一步 ...
- android基于MVP小说网络爬虫、宝贝社区APP、仿虎扑钉钉应用、滑动阴影效果等源码
Android精选源码 android宝贝社区app源码 android仿Tinder最漂亮的一个滑动效果 android仿滴滴打车开具发票页,ListView粘性Header Android基于MV ...
随机推荐
- sublime 插件总结
sublime的强大之处在于其丰富的插件,记录一下常用的插件. 1.Color Highlighter(识别代码中的颜色) 默认如下显示 做如下修改,打开插件默认设置,并复制到用户设置,将 " ...
- 一个java页游服务器框架
一.前言 此游戏服务器架构是一个单服的形式,也就是说所有游戏逻辑在一个工程里,没有区分登陆服务器.战斗服务器.世界服务器等.此架构已成功应用在了多款页游服务器 .在此框架中没有实现相关业务逻辑,只有简 ...
- Make something people want
<黑客与画家>开头首先介绍了书的作者格雷厄姆的其人其事,他的成长涉猎很多,大学学哲学,研究生学计算机,博士时对绘画感兴趣,后来做了两年画家,但是入不敷出,后来他和朋友开始合伙开发一个搭建网 ...
- MVC知识进阶01
下面是在项目中有关于MVC的知识总结,有些地方若不对,请指出. 一:MVC的基本知识 1 名词解释 *惯例优先原则<约定大于配置>:是一种开发设计模式,说是在项目里面使用事先规定的命 ...
- .Net实现拉勾网爬虫
前几天看到一个.NET Core写成的爬虫,有些莫名的小兴奋,之前一直用集搜客去爬拉勾网的招聘信息,这个傻瓜化工具相当于用HTML模板页去标记DOM节点,然后在浏览器窗口上模拟人的浏览行为同时跟踪节点 ...
- 下一代USB接口将支持双向拔插,于明年亮相
近日,USB接口标准制定组织表示新一代USB接口将于明年年中亮相,而其名称目前被暂定为了USB Type-C.该组织表示USB Type-C标准将允许制造商采用更纤薄的接口设计,在实用性大大提高的同时 ...
- Eclipse导入Java项目时“No projects are found to import”错误的处理
用Eclipse导入Java项目时,经常会出现“No projects are found to import”错误(尤其是导入网上下载的项目时),这是因为文件夹里面没有.project和.class ...
- java中获取文件或文件夹的路径方法
获取当前类的所在工程路径; 如果不加"/" File f = new File(this.getClass().getResource("").getPath( ...
- Go学习笔记之基础数据类型
http://studygolang.com/articles/1348 1 整数 在 Go 语言中,如果不加特殊前缀,都是10进制表示,例如:“100” 整数可以直接用指数形式,例如:“1E9”,意 ...
- 减小服务器负担,Apache启用mod_expires模块
mod_expires可以减少10%左右的重复请求,让重复的用户对指定的页面请求结果都CACHE在本地,根本不向服务器发出请求. 在使用之前,首先要确认一下”mod_expires”模组是否有启用.如 ...