RxBus并不是框架,而是一种类似观察者的模式。类似效果的还有EventBus和otto,
但是如果项目中使用了Rx响应式编程,那么用RxBus这种事件通信可以加深对响应式编程的熟练,以及不需要再引用任何库,它就是一个简单的类:
public class RxBus {
private static RxBus sRxBus;
private final Subject
看一下注释1:
查看源码,有PublishSubject的示例:
PublishSubject
PublishSubject和 通常用的 Observable.subscribe(observer)或者Observable.subscribe(subscriber)不一样,Observable.subscribe会触发事件,
而PublishSubject.subscribe不会马上触发事件,而是onNext的时候才会触发。
所以订阅的subscriber或者observer 只能收到 它后面的onNext的事件。
看一下注释2:
查看源码,有SerializedSubject 有这么一段注释:
Wraps a {@link Subject} so that it is safe to call its various {@code on} methods from different threads. When you use an ordinary {@link Subject} as a {@link Subscriber}, you must take care not to call its {@link Subscriber#onNext} method (or its other {@code on} methods) from multiple threads, as this could lead to non-serialized calls, which violates the Observable contract and creates an ambiguity in the resulting Subject.
意思就是说 你用普通的Subject 发射onNext的时候要注意不能在不同的线程发射,会引发线程安全的。
通常我们用 mySafeSubject = new SerializedSubject( myUnsafeSubject ); 将普通的Subject包裹进SerializedSubject 可以解决线程安全的问题。
继续看SerializedSubject 的源码,看一下它是怎么解决线程安全的问题。
public class SerializedSubject<T, R> extends Subject<T, R> {
private final SerializedObserver observer;
private final Subject actual;
public SerializedSubject(final Subject actual) {
super(new OnSubscribe() {
@Override
public void call(Subscriber super R> child) {
actual.unsafeSubscribe(child);
}
});
this.actual = actual;
this.observer = new SerializedObserver(actual);
}
@Override
public void onCompleted() {
observer.onCompleted();
}
@Override
public void onError(Throwable e) {
observer.onError(e);
}
//原来SerializedSubject把onCompleted、onError、onNext都交给了SerializedObserver去处理。
@Override
public void onNext(T t) {
observer.onNext(t);
}
@Override
public boolean hasObservers() {
return actual.hasObservers();
}
}
SerializedSubject把onNext交给SerializedObserver去处理了,接着看看SerializedObserver的源码。
还是看看源码的注释:
When multiple threads are emitting and/or notifying they will be serialized by:
Allowing only one thread at a time to emit
Adding notifications to a queue if another thread is already emitting
Not holding any locks or blocking any threads while emitting
有道词典翻译加个人理解:只允许onNext在同一时间只能在一个线程发射,
如果已经存在一个线程发射onNext,那么另一个发射onNext将添加到队列中,
在发射onNext过程中,不会持有任何锁和阻塞线程。
@Override
public void onNext(T t) {
if (terminated) {
return;
}
synchronized (this) {
if (terminated) {
return;
}
//emitting为true,说明有线程已经正在发射onNext中
if (emitting) {
FastList list = queue;
if (list == null) {
list = new FastList();
queue = list;
}
//把现在准备要发射的事件加到队列中,然后直接返回
list.add(nl.next(t));
return;
}
emitting = true;
}
try {
//没有线程在发射onNext就直接 onNext
actual.onNext(t);
} catch (Throwable e) {
terminated = true;
Exceptions.throwOrReport(e, actual, t);
return;
}
for (;;) {
for (int i = 0; i < MAX_DRAIN_ITERATION; i++) {
FastList list;
synchronized (this) {
list = queue;
//如果 队列 是空的,直接返回,发射ing 也置为false
if (list == null) {
emitting = false;
return;
}
queue = null;
}
for (Object o : list.array) {
if (o == null) {
break;
}
try {
//下面分析
//事件为 COMPLETED或者ERROR ,才终止
if (nl.accept(actual, o)) {
terminated = true;
return;
}
} catch (Throwable e) {
terminated = true;
Exceptions.throwIfFatal(e);
actual.onError(OnErrorThrowable.addValueAsLastCause(e, t));
return;
}
}
}
}
}
上面看到了nl.accept(actual, o),跟进去。 看到只有事件为 COMPLETED或者ERROR,才返回true,如果为ON_NEXT,依旧 死循环 for (;;)
public boolean accept(Observer super T> o, Object n) {
if (n == ON_COMPLETED_SENTINEL) {
o.onCompleted();
return true;
} else if (n == ON_NEXT_NULL_SENTINEL) {
o.onNext(null);
return false;
} else if (n != null) {
if (n.getClass() == OnErrorSentinel.class) {
o.onError(((OnErrorSentinel) n).e);
return true;
}
o.onNext((T) n);
return false;
} else {
throw new IllegalArgumentException("The lite notification can not be null");
}
}
public void post(Object o) {
//bus就是PublishSubject,所以随时发射onNext都可以
mBus.onNext(o);
}
public Observable toObservable(Class eventType) {
return mBus.ofType(eventType);
}
public final Observable ofType(final Class klass) {
return filter(InternalObservableUtils.isInstanceOf(klass)).cast(klass);
}
filter 根据传进来的类过滤,post的时候只发射给对应的订阅者
cast 类型转换
本文是分析源码以及查看资料,然后写的,有哪些地方不对的欢迎指出。
哈哈O(∩_∩)O哈哈~。