博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Android]基于RxJava、RxAndroid的EventBus实现
阅读量:5865 次
发布时间:2019-06-19

本文共 5851 字,大约阅读时间需要 19 分钟。

以下内容为原创,欢迎转载,转载请注明

来自天天博客: 

 

Github:

EventBus的作用是发布/订阅事件总线,因为项目中用到RxJava、RxAndroid,所以完全可以使用RxJava、RxAndroid来实现EventBus。

 

1. 编写RxBus,用于存储所有事件Subjects。

事件是传递的最小单位,可以把任何类作为一个事件。

RxBus代码如下:

1 /** 2  * Author: wangjie 3  * Email: tiantian.china.2@gmail.com 4  * Date: 6/11/15. 5  */ 6 public class RxBus { 7     private static final String TAG = RxBus.class.getSimpleName(); 8     private static RxBus instance; 9     public static boolean DEBUG = false;10 11     public static synchronized RxBus get() {12         if (null == instance) {13             instance = new RxBus();14         }15         return instance;16     }17 18     private RxBus() {19     }20 21     private ConcurrentHashMap
> subjectMapper = new ConcurrentHashMap<>();22 23 @SuppressWarnings("unchecked")24 public
Observable
register(@NonNull Object tag, @NonNull Class
clazz) {25 List
subjectList = subjectMapper.get(tag);26 if (null == subjectList) {27 subjectList = new ArrayList<>();28 subjectMapper.put(tag, subjectList);29 }30 31 Subject
subject;32 subjectList.add(subject = PublishSubject.create());33 if (DEBUG) Log.d(TAG, "[register]subjectMapper: " + subjectMapper);34 return subject;35 }36 37 public void unregister(@NonNull Object tag, @NonNull Observable observable) {38 List
subjects = subjectMapper.get(tag);39 if (null != subjects) {40 subjects.remove((Subject) observable);41 if (ABTextUtil.isEmpty(subjects)) {42 subjectMapper.remove(tag);43 }44 }45 46 if (DEBUG) Log.d(TAG, "[unregister]subjectMapper: " + subjectMapper);47 }48 49 public void post(@NonNull Object content) {50 post(content.getClass().getName(), content);51 }52 53 @SuppressWarnings("unchecked")54 public void post(@NonNull Object tag, @NonNull Object content) {55 List
subjectList = subjectMapper.get(tag);56 57 if (!ABTextUtil.isEmpty(subjectList)) {58 for (Subject subject : subjectList) {59 subject.onNext(content);60 }61 }62 if (DEBUG) Log.d(TAG, "[send]subjectMapper: " + subjectMapper);63 }64 }

如上述代码,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类型的事件为例)

1 Observable
addOb = RxBus.get()2 .register("addFeedTag", String.class);3 4 addOb.observeOn(AndroidSchedulers.mainThread())5 .subscribe(s -> {6 // todo: Accept event and process here7 });

如上,注册了一个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. 接收事件,然后处理

1 @Accept2 public void onPostAccept(Object tag, FeedItemClickEvent event) {3   Logger.d(TAG, "onPostAccept event: " + event);4   Feed feed = event.getFeed();5   // 跳转到feed详情页面...6 }

如上,这里只需要编写一个方法,加上Accept注解,然后在方法中进行事件处理即可。

注意:方法名可以任意

方法参数一:必须为Object类型的tag;

方法参数二,如果这个方法只接收一种事件,则写明具体的事件类型,如上;如果这个方法接收多种事件,则类型需要为Object。

4. 反注册Observer

这一步也可以省略掉。

 

接收多种事件:

1 @Accept( 2             acceptScheduler = AcceptScheduler.NEW_THREAD, 3             value = { 4                     @AcceptType(tag = ActionEvent.CLOSE, clazz = String.class), 5                     @AcceptType(tag = ActionEvent.BACK, clazz = String.class), 6                     @AcceptType(tag = ActionEvent.EDIT, clazz = String.class), 7                     @AcceptType(tag = ActionEvent.REFRESH, clazz = String.class) 8             } 9     )10     public void onPostAccept(Object tag, Object actionEvent) {11         Logger.d(TAG, "[ActionEvent]onPostAccept action event name: " + actionEvent);12         // todo: Accept event and process here (in new thread)13     }

这里@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:

1 /** 2  * Author: wangjie 3  * Email: tiantian.china.2@gmail.com 4  * Date: 6/15/15. 5  */ 6 public class MyApplication extends Application { 7     private Executor acceptExecutor = Executors.newCachedThreadPool(); 8     private Handler handler = new Handler(Looper.getMainLooper()); 9 10     @Override11     public void onCreate() {12         super.onCreate();13         RxBus.DEBUG = true;14 15         DefaultAcceptConfiguration.getInstance().registerAcceptConfiguration(new DefaultAcceptConfiguration.OnDefaultAcceptConfiguration() {16             @Override17             public Executor applyAcceptExecutor() {18                 return acceptExecutor;19             }20 21             @Override22             public Handler applyAcceptHandler() {23                 return handler;24             }25         });26     }27 }

因为需要对Accept和AcceptType注解的解析,所以项目的BaseActivity需要使用,然后实现parserMethodAnnotations()方法,使用对注解进行解析。

 

参考:

 

本文转自天天_byconan博客园博客,原文链接:http://www.cnblogs.com/tiantianbyconan/p/4578699.html
,如需转载请自行联系原作者
你可能感兴趣的文章
java ShutdownHook介绍与使用
查看>>
Eclipse的 window-->preferences里面没有Android选项
查看>>
《麦田里的守望者》--[美]杰罗姆·大卫·塞林格
查看>>
遇到的那些坑
查看>>
央行下属的上海资信网络金融征信系统(NFCS)签约机构数量突破800家
查看>>
[转] Lazy evaluation
查看>>
常用查找算法总结
查看>>
grep 零宽断言
查看>>
被神话的大数据——从大数据(big data)到深度数据(deep data)思维转变
查看>>
修改校准申请遇到的问题
查看>>
【DL-CV】浅谈GoogLeNet(咕咕net)
查看>>
python大佬养成计划----win下对数据库的操作
查看>>
(cons '(〇 . 前言) 《为自己写本-Guile-书》)
查看>>
监控软件zabbix之安装
查看>>
No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=arm64, VALID_ARCHS=armv7 armv7s)
查看>>
Exchange Server 2016 独立部署/共存部署 (七)—— DAG功能测试
查看>>
对RTMP视频流进行BitmapData.draw()出错的解决办法
查看>>
Linux 进程中 Stop, Park, Freeze【转】
查看>>
Spark修炼之道(基础篇)——Linux大数据开发基础:第九节:Shell编程入门(一)...
查看>>
Duplicate Symbol链接错误的原因总结和解决方法[转]
查看>>