Android事件通知工具:RxBus在Eclipse和AS中的实践

来源:互联网 发布:韩寒 代笔 知乎 编辑:程序博客网 时间:2024/06/17 08:37

相信大家在进行Android开发的时候最头疼的就是这边有一个点击事件,需要传递到其他界面显示结果,或者说有一处变化了需要告诉许多界面去刷新界面。相信经常使用Fragment进行开发的小伙伴们经常会遇到Fragment界面相互影响,相互刷新的各种负责的业务。这些都是我们需要使用到事件通知的场景。

最初我们使用的是Android自身携带的广播Broadcast来解决这个问题,在需要接收的地方注册广播接收监听,然后通过context.sendBroadcast来发送事件,通过Intent来传递数据。这种如果在最初使用的话还是比较简单的,但是如果需要通知的事件多了的话,整个项目里面就都是sendBroadcast以及registerReceiver,广播使用得不好还很容易出现内存泄露,代码的逻辑性以及程序的稳定性将会大打折扣,使用起来也是极其不方便。

后来学习了java的设计模式之观察者模式,自己设计了一套事件通知工具,其实质还是“接口回调监听“,使用起来可以说比广播好了多了,但是嘛,在使用的过程中还是会出现这些或者那些的问题,最主要的问题就是接口回调不能给自由地切换线程,在子线程回调出来的就是子线程,在主线程回调出来的就是主线程,不好进行线程控制。这也是为什么之前EventBus事件工具如此火的原因所在,它可以控制事件触发的子线程还是主线程。

但是仅仅是EventBus根本满足不了我对代码简洁、使用方便、安全的要求。我理想中的事件工具应该是这样的:只需一行代码就可以完成事件动作的注册、只需一行代码就可以完成事件的传递、只需一行代码就可以轻松地注销事件监听,并且可以自由地控制线程,而串联这三个的只需要一个事件TAG即可,后面只需要维护这个事件TAG就行了。不需要像EventBus那样在每个Activity或者Fragment里面写onEventMainThread这种笨笨的代码。那么这样的事件工具真的有吗?当然有啦,那就是接下来我要隆重地推荐以及介绍的RxBus!

RxBus顾名思义是基于RxJava这个目前火得不能再火的项目改造而成的,RxBus继承了RxJava的最大特性:变化【转化】,通过它我们可以轻松地进行线程控制,代码也起来也是极其简洁明了。RxBus的代码很简洁,只有一个java类,如下:

/** * RxBus *  * @author xx *  */public class RxBus {private ConcurrentHashMap> maps = new ConcurrentHashMap>();private static RxBus sInstance;public static RxBus get() {if (sInstance == null) {synchronized (RxBus.class) {if (sInstance == null) {sInstance = new RxBus();}}}return sInstance;}/** * 简单以对象的类名注册 * @param o * @return */public  Observable simpleRegister(@NonNull Object o) {return register(o.getClass().getSimpleName());}/** * 注册订阅 * @param tag * @return */public  Observable register(@NonNull Object tag) {List subjects = maps.get(tag);if (subjects == null) {subjects = new ArrayList();maps.put(tag, subjects);}Subject subject = PublishSubject. create();subjects.add(subject);return subject;}/** * 注销tag制定的订阅 * @param tag */public void unregister(@NonNull Object tag, @NonNull Observable observable) {List subjects = maps.get(tag);if (subjects != null) {subjects.remove((Subject) observable);if (subjects.isEmpty()) {maps.remove(tag);}}}/** * 注销tag所有的订阅 * @param tag */public void unregisterAll(@NonNull Object tag) {List subjects = maps.get(tag);if (subjects != null) {maps.remove(tag);}}public void post(@NonNull Object tag) {post(tag, tag);}/** * 发送指定tag的事件 * @param tag * @param o */@SuppressWarnings("unchecked")public void post(@NonNull Object tag, @NonNull Object o) {List subjects = maps.get(tag);if (subjects != null && !subjects.isEmpty()) {for (Subject s : subjects) {s.onNext(o);}}}}public class RxManager {private final static String TAG = "RxManager";private static RxManager sInstance;private RxBus mRxBus = RxBus.get();/** 管理Subscribers订阅,防止内存泄漏 */private ConcurrentHashMap maps = new ConcurrentHashMap();public static RxManager get() {if (sInstance == null) {synchronized (RxManager.class) {if (sInstance == null) {sInstance = new RxManager();}}}return sInstance;}/** *  * RxBus注入监听 *  * @param eventName *  * @param action1 */public  void onMainThread(Object eventName, Action1 action1) {Observable Observable = mRxBus.register(eventName);/* 订阅管理 */add(eventName, Observable.observeOn(AndroidSchedulers.mainThread()).subscribe(action1, new Action1() {@Overridepublic void call(Throwable throwable) {Log.e(TAG, throwable.getMessage());}}));}/** *  * RxBus注入监听 *  * @param eventName *            事件名 * @param action1 */public  void on(Object eventName, Action1 action1) {Observable Observable = mRxBus.register(eventName);/* 订阅管理 */add(eventName, Observable.subscribe(action1, new Action1() {@Overridepublic void call(Throwable throwable) {Log.e(TAG, throwable.getMessage());}}));}/** * 单纯的Observables 和Subscribers管理 *  * @param m */public void add(Object eventName, Subscription m) {/* 订阅管理 */CompositeSubscription subscription = maps.get(eventName);if (subscription == null) {subscription = new CompositeSubscription();maps.put(eventName, subscription);}subscription.add(m);}/** *  * 单个presenter生命周期结束,取消订阅和所有rxbus观察 */public void clear(@NonNull Object eventName) {CompositeSubscription subscription = maps.get(eventName);if (subscription != null) {subscription.unsubscribe(); // 取消订阅maps.remove(eventName);}mRxBus.unregisterAll(eventName);}// 发送rxbuspublic void post(Object tag) {mRxBus.post(tag);}// 发送rxbuspublic void post(Object tag, Object content) {mRxBus.post(tag, content);}}

这里我就不具体阐述RxBus以及RxManager是如何起到事件通知的效果的,想了解的可以自行去了解Rxjava的特性。

这里我只介绍如何使用RxBus。

1、首先是事件动作注册:

RxManager.get().on注册的事件回调后返回的还是当前的线程,RxManager.get().onMainThread注册的事件回调后返回的直接是主线程。

2、其次是事件的通知:

直接调用RxManager.get().post(Event_Key) :不携带数据的事件

RxManager.get().post(Event_Key,object) :携带数据的事件

     

3、最后就是事件监听的销毁:

直接调用RxManager.get().clear(Event_Key)即可。

以上三部即可完成事件通知的全过程,是不是很方便啊,O(∩_∩)O~~,实在是太给力了!

接下在我将介绍如何在Eclipse以及AS中使用:

Eclipse 需要下载下载rxjava-1.2.4.jar以及rxandroid-0.25.0.jar,并引用依赖即可。下载地址:https://repo1.maven.org/maven2/io/reactivex/rxjava/

需要Eclipse使用Demo的可点击下载(业界良心,不要分)

AS 直接在build.gradle中配置依赖即可:

compile 'io.reactivex:rxjava:1.2.9'compile 'io.reactivex:rxandroid:1.2.1'