上一篇文章我们介绍了Otto EventBus, 我们发现EventBus用的就是典型的观察者模式,也就是包含4个主要元素 ,订阅 ,订阅者,事件以及总线,这个和我们之前介绍的RxJava是基本一致的,那么我们可以用RxJava来实现EventBus么,答案是肯定的,我们接着一步步来实现。
文章目录:
添加依赖
因为我们是用RxJava来实现,所以只需添加RxJava的依赖就可以了
compile ‘io.reactivex:rxandroid:1.1.0’
compile ‘io.reactivex:rxjava:1.1.0’
实现RxBus
public class RxBus {
private static RxBus rxBus;
private final Subject<Object, Object> _bus = new SerializedSubject<>(PublishSubject.create());
private RxBus() {
}
public static RxBus getInstance() {
if (rxBus == null) {
synchronized (RxBus.class) {
if (rxBus == null) {
rxBus = new RxBus();
}
}
}
return rxBus;
}
public void post(Object o) {
_bus.onNext(o);
}
public Observable<Object> toObserverable() {
return _bus;
}
}
发送事件
RxBus.getInstance().post(Object event)
接收事件
rxSubscription = RxBus.getInstance().toObserverable()
.subscribe(new Action1() {
@Override
public void call(Object event) {
//the code when subcrbe trige
}
});
内存回收
和其他eventBus一样,使用完,需要取消订阅,以完成内存回收,防止OOM, 这里我们要在订阅的地方取消订阅
@Override
public void onDestroy(Context context) {
if (rxSubscription != null && !rxSubscription.isUnsubscribed()) {
rxSubscription.unsubscribe();
}
super.onDestroy(context);
}
我们可以把这个方法封装在对应基类中,在基类中做处理,这样大家就不用那么麻烦, 当然这里推荐一个处理Rx生命周期的开源库 RxLifecycle,有2000多star,有兴趣的同学可以研究下~
异常处理
由于RxJava 一旦发生异常就会调用onError,进而订阅事件完成并停止,为了让订阅可以正常进行,我们必须对订阅异常进行一些处理,异常处理主要有两种方式:1.自动重新订阅 2.捕捉
1.自动重新订阅
private void subscribeEvent(){
RxBus.getDefault().toObservable(Event.class)
// 使用操作符过程中,无需try,catch,直接使用
.subscribe(new Subscriber<Event>() {
@Override
public void onCompleted() {
subscribeEvent();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
subscribeEvent();
}
@Override
public void onNext(Event event) {
// 直接处理接收的事件
}
});
}
这个方法很简单粗暴,但是会有问题 : 1.如果错误事件不断发生,那么可能导致error死循环 2.不可用于sticky事件(关于sticky事件可以参考 这篇文章)
捕获
这个方法也是同样简单,就是把异常打印,但是程序继续执行
RxBus.getDefault().toObservableSticky(EventSticky.class) // 建议在Sticky时,在操作符内主动try,catch
.map(new Func1<EventSticky, EventSticky>() {
@Override
public EventSticky call(EventSticky eventSticky) {
try {
// 变换操作
} catch (Exception e) {
e.printStackTrace();
}
return eventSticky;
}
})
.subscribe(new Action1<EventSticky>() {
@Override
public void call(EventSticky eventSticky) {
try {
// 处理接收的事件
} catch (Exception e) {
e.printStackTrace();
}
}
});
简单来说,就是在 ActionN 以及FuncN 中加入 try…catch…这样的异常处理,现在我们自己的项目也是这样做的
线程切换
和RxJava一直,请看之前关于RxJava的介绍
是时候用RxBus取代Otto EventBus么?
1.Otto EventBus已经停止开发,也就是说,对后面兼容不保证
2.在这篇文章 RxBus真的能替代EventBus吗? 做了分析,RxBus在订阅者数量很大的情况下,性能下降非常明显
所以,我们现在在项目中需要还是使用EventBus,但是也会在尝试RxBus, 等待RxBus全面成熟。