RxBus解释:
- RxBus是一个高效的事件总线机制。作用是可以代替传统的接口回调函数,在Fragment,Activity,Service之间进行数据通信。特点是代码简洁,省却了很多繁琐的回调的编写,让代码可读性变得更高。同时结合RxJava的线程切换机制,能够更加高效便捷。
- 而且RxBus的设计优势还能结合RxJava的事件流,能够实现更多的变换操作,比传统的EventBus,要更加的方便快捷,代码可读性也更高。
原理:
- 首先我们来回忆一下EventBus的大概功能。其实不外乎就是基于观察者模式一样的设计,在工程代码的某一处,将某个事件(对象)进行抛出。
- 在观察者列表中的观察者,接收到这个事件(对象)后,做出相应的操作。
- 其实抛出事件(对象),不就等同于是RxJava事件流中的上游的角色
- 接收事件(对象),也就等同于RxJava事件流中的上游的角色。
- 从这么来看,RxJava已经天然支持这一需求的前置条件了。剩下来的不过是需要将上下游链接起来。事实上,这也只是代码设计方式的问题而已。
- RxBus基于这一规则,把RxBus本身编写成一个单例。当上游需要抛出事件(对象)的时候,调用单例发射事件(对象)。下游也通过单例对象去进行订阅操作。这样就做到在任何时候都能轻而易举地实现总线通信的效果了。
- 来吧,说干就干!
选用合适的单例对象
我们说了需要一个单例,这个很简单。但是我们需要这个单例能够实现自己作为RxJava事件流上游、下游的功能,这个我们需要邀请RxBus中的核心成员:
Subject
Subject是RxJava提供的一个抽象类,我们来看一看它的继承关系:
public abstract class Subject<T> extends Observable<T> implements Observer<T>
从上面我们可以得到一个结论,也就是Subject既能充当事件流的上游,也可以充当事件流的下游。那我们通过Subject来实现RxBus的功能就好啦。
因为我们目前需要使用的RxBus的总线玩法,还不至于需要处理太过海量的信息数据的发送,因此暂时不做BackPressure的考虑。那我们就选定了Subjcet的子类:
PublishSubject
具体实现:
构造实例
- 单例中,我们需要创建一个PublishSubject对象,用做处理事件流:
RxBus() {
mRxBus = PublishSubject.create().toSerialized();
}
- 如上,我们在单例的构造器中实例化PublishSubject即可。
- PublishSubject不支持直接调用构造器实例化,只能调用其自身的create()函数。
- 同时,调用toSerialized()函数,是为了保证事件流的过程中是线程安全的。
事件的处理
- 刚刚说到了,RxBus需要抛出事件,也需要注册观察者,那么肯定需要两个函数:
//抛出事件(这里选用Object以便调用者可以发送任意类型事件)
public void postEvent(Object event);
//注册观察者,这里传入Class对象,表示接受观察者需要接受的事件
public <T> Observable<T> toSubscriber(Class<T> type);
- postEvent()就很好理解了,在程序的任何位置,需要抛出事件的时候,直接调用这个API就完事了,方便快捷。
- toSubscribe()的方案,我们可以看下如下代码:
RxBus.INSTANCE.toSubscriber(String.class)//声明接收任意地方发送的String字符串
.observeOn(AndroidSchedulers.mainThread())//在Android UI线程中处理下游事件回调
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
Log.d("RxBus", "onNext: "+s);//收到字符串时,打印出来
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
- 显而易见的,这样的调用方式,清晰明了,而且还能完美结合RxJava的关键字,线程控制API,简直美滋滋。