您的位置:首页 > 编程语言 > Java开发

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

2017-05-18 14:30 417 查看
相信大家在进行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<Object, List> maps = new ConcurrentHashMap<Object, List>();
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() {
@Override
public 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() {
@Override
public 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);

}

// 发送rxbus
public void post(Object tag) {
mRxBus.post(tag);
}

// 发送rxbus
public 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'GitHub项目地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息