今年三月份开始在项目里面引入Rxjava,用了这么久也就只是用刀了flatmap,just 以及线程调度,感觉完全没用起来,闲下来的时候就看看源码,发现以前写的代码甚至线程调度有些都可能用错了,汗颜!还是先了解下原理再深入的使用吧。
先从观察者模式入手:观察者 、被观察者
1.观察者:
public interface Observer<T> {
/**
* Provides the Observer with the means of cancelling (disposing) the
* connection (channel) with the Observable in both
* synchronous (from within {@link #onNext(Object)}) and asynchronous manner.
* @param d the Disposable instance whose {@link Disposable#dispose()} can
* be called anytime to cancel the connection
* @since 2.0
*/
void onSubscribe(@NonNull Disposable d);
/**
* Provides the Observer with a new item to observe.
* <p>
* The {@link Observable} may call this method 0 or more times.
* <p>
* The {@code Observable} will not call this method again after it calls either {@link #onComplete} or
* {@link #onError}.
*
* @param t
* the item emitted by the Observable
*/
void onNext(@NonNull T t);
/**
* Notifies the Observer that the {@link Observable} has experienced an error condition.
* <p>
* If the {@link Observable} calls this method, it will not thereafter call {@link #onNext} or
* {@link #onComplete}.
*
* @param e
* the exception encountered by the Observable
*/
void onError(@NonNull Throwable e);
/**
* Notifies the Observer that the {@link Observable} has finished sending push-based notifications.
* <p>
* The {@link Observable} will not call this method if it calls {@link #onError}.
*/
void onComplete();
}
应该是观察者顶级父类,里面就只有几个抽象的方法,注释很详细了,就是处理事件各个阶段的回调。
2.被观察者:
public interface ObservableSource<T> {
/**
* Subscribes the given Observer to this ObservableSource instance.
* @param observer the Observer, not null
* @throws NullPointerException if {@code observer} is null
*/
void subscribe(@NonNull Observer<? super T> observer);
}
就一个方法。
3.流程:一般的观察者模式是 注册成为观察者之后 就可以收到被观察者的 回调的各种数据了,这里反过来了,需要被观察者订阅观察者,然后一样的把各种信息回调给 观察者。
ObservableSource.subscribe(observer)
但是很明显ObservableSource没有实现订阅之后的信息回调,只能去它的子类里面找。
一看实现类,发现一堆!
应该实现方式都差不多,只看常用的Observable 好了
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
//这里不用太在意,两种情况要么直接返回传进来的参数,要么自己手动返回一另外一个observer
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable has been set or not
// can't call onSubscribe because the call might have set a Subscription already
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
重写subscribe 之后就事件传递到subscribeActual(observer) 方法里面了
protected abstract void subscribeActual(Observer<? super T> observer);
这里同样是一个抽象方法,还是没有实现订阅之后事件从被观察者回调给 观察者,那只能继续往下找
就从最简单的Observable.just() 入手
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> just(T item) {
ObjectHelper.requireNonNull(item, "The item is null");
return RxJavaPlugins.onAssembly(new ObservableJust<T>(item));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
这里返回ObservableJust 对象或者我们自定义的 observable 对象,自定义的话要自己来实现从被观察者到观察者的分发了。这里只看它写好的。
public final class ObservableJust<T> extends Observable<T> implements ScalarCallable<T> {
private final T value;
public ObservableJust(final T value) {
this.value = value;
}
@Override
protected void subscribeActual(Observer<? super T> s) {
ScalarDisposable<T> sd = new ScalarDisposable<T>(s, value);
s.onSubscribe(sd);
sd.run();
}
@Override
public T call() {
return value;
}
}
上面提到subscribe 之后事件传到了subscribeActual()方法里面
4. observer 回调了接口 observer .onsubscribe()里面的参数暂时无关
@Override
public void run() {
if (get() == START && compareAndSet(START, ON_NEXT)) {
observer.onNext(value);
if (get() == ON_NEXT) {
lazySet(ON_COMPLETE);
observer.onComplete();
}
}
}
5.run 方法里面也可以看到onNext(),onComplete()方法了,没看到onerror(),回到前面看一下
原来这里简单粗暴的try-catch 掉了,如果有异常直接抛异常出来,所以没机会回调onerror。
6.再来看一下其他实现,比如可以捕捉异常的情况
observable.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
System.out.println("accept");
Object c = null;
System.out.println(c.toString()+"错误点");
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("throwable");
}
});
跑一下,竟然测试通过了,而且也打印了 throwable
7.
public interface Consumer<T> {
/**
* Consume the given value.
* @param t the value
* @throws Exception on error
*/
void accept(T t) throws Exception;
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {
return subscribe(onNext, onError, Functions.EMPTY_ACTION, Functions.emptyConsumer());
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
Action onComplete, Consumer<? super Disposable> onSubscribe) {
ObjectHelper.requireNonNull(onNext, "onNext is null");
ObjectHelper.requireNonNull(onError, "onError is null");
ObjectHelper.requireNonNull(onComplete, "onComplete is null");
ObjectHelper.requireNonNull(onSubscribe, "onSubscribe is null");
LambdaObserver<T> ls = new LambdaObserver<T>(onNext, onError, onComplete, onSubscribe);
subscribe(ls);
return ls;
}
consumer 是一个扩展,但是最终也是将他打包成一个 lambdaobserver 对象,然后subscribe 后面的流程都是一样的,说明onerror 只能在这个lambdaobserver 里面了进去看看
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.setOnce(this, s)) {
try {
onSubscribe.accept(this);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.dispose();
onError(ex);
}
}
}
可以看到在 onsubscribe 里面回调了accept,报错的话会取消订阅并且回调onerror
@Override
public void onError(Throwable t) {
if (!isDisposed()) {
lazySet(DisposableHelper.DISPOSED);
try {
onError.accept(t);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
RxJavaPlugins.onError(new CompositeException(t, e));
}
} else {
RxJavaPlugins.onError(t);
}
}
到这订阅和事件回调就看完啦!
总结:observable.subscribe(observer) ====> observable.subscribeactual(observer)(这个方法里面会去回调observer的方法)