前言:
想要看Rxjava的源码已经很久了,一直不能坚持看下去。在这个想法的基础上打算边看边写一篇文章出来,也算是我的第一篇分享文章。
文笔不好,写的也许会比较干,理解也不一定到位,还请看官多多见谅。
我也会把我的一些疑问写入到文章里面,还望各位多多评论,不吝赐教。
创建型操作符-Create
Observable.subscribe(Observer)
创建一个Observable并订阅它,这是最基本的一个操作,代码如下:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onComplete();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer i) {
Log.d("BlackC0", "onNext: " + i);
}
@Override
public void onError(Throwable e) {
Log.d("BlackC0", "onError: "+ e.toString());
}
@Override
public void onComplete() {
Log.d("BlackC0", "onComplete()");
}
});
那么这里的emitter 是由谁创建的,他们订阅的时候做了些什么呢? 我们来看看具体的方法。
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null"); //判空
try {
observer = RxJavaPlugins.onSubscribe(this, observer);//全局配置拦截
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");//判空
subscribeActual(observer);//这个是主要方法 也是Observable的抽象方法
} 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);//全局配置拦截Throwable
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
--------------------------------------------------------------------------------------------
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));//也是经过全局拦截再最终返回的
}
--------------------------------------------------------------------------------------------
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);//可以看到emitter是这里创建并且实现Disposable的接口
try {
source.subscribe(parent);//这里的subscribe方法和外面的subscribe方法是不一样的
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
这里首先创建了一个Observable,并且实例了一个匿名内部类ObservableOnSubscribe,实现了ObservableOnSubscribe.subscribe()方法。然后创建了一个Observer,并订阅了Observable,通过Observable.subscribe()方法建立订阅关系。在Observable.subscribeActual()这个实际的订阅方法里面, observer被包装成了Emitter,调用了Observable里的ObservableOnSubscribe调用了ObservableOnSubscribe.subscribe()方法,并把emitter发送出去。
OnNext()、OnError()、onComplete()
通过以上的代码,我们知道这样子就完成了一个订阅关系,那么订阅开始之后,数据是怎么通过Observable发射到 Observer的呢。我们知道数据的发送是通过emitter进行的,所以接下来我们就来看看Emitter的实例过程。
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
//在这里我们可以看到onNext()是不允许传空值的,否则会报错
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {//判断订阅是否结束
observer.onNext(t);
}
}
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {//emitter的onError()会被tryOnError拦截最后再丢出到Observer层
RxJavaPlugins.onError(t);//全局配置拦截Throwable
}
}
@Override
public boolean tryOnError(Throwable t) {
if (t == null) {
t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
}
if (!isDisposed()) {
try {
observer.onError(t);
} finally {
dispose();//可以看到为啥onError()之后就会订阅终止,因为这里取消了订阅
}
return true;
}
return false;//从这里可以看出如果再订阅取消之后 仍有错误从这里抛出的话 就会到全局配置那里去
//而如果全局配置没有拦截错误的话 那么这里的错误就会直接抛出到主线程 导致崩溃
}
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();//这里也是,onComplete之后就自动取消订阅了
} finally {
dispose();
}
}
}
@Override
public void setDisposable(Disposable d) {
DisposableHelper.set(this, d);
}
@Override
public void setCancellable(Cancellable c) {
setDisposable(new CancellableDisposable(c));
}
@Override
public ObservableEmitter<T> serialize() {
return new SerializedEmitter<T>(this);
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
我们可以看到 Observer的OnNext()、OnError()、OnComplete()方法都是由Emitter直接调用的,这个emitter只是实例化的其中一个emitter,如果想要自定义一些拦截OnNext()的方法,也可以通过实现自定义的Emitter去拦截。
Disposable
订阅、数据传递经过上面的代码,都有一定的了解了。那么订阅的主动取消,是怎么一个流程呢? 我们现在有的线索就是emitter实现的两个方法:dispose()和isDisposed()。 接下来我们就一起看看这里面的方法写了啥。由于代码比较长,我就把主要的几个方法节选出来。
public enum DisposableHelper implements Disposable {
/**
* The singleton instance representing a terminal, disposed state, don't leak it.
*/
DISPOSED
;
public static boolean isDisposed(Disposable d) {
return d == DISPOSED;
}
public static boolean dispose(AtomicReference<Disposable> field) {
Disposable current = field.get();
Disposable d = DISPOSED;
if (current != d) {
current = field.getAndSet(d);
if (current != d) {
if (current != null) {
current.dispose();
}
return true;
}
}
return false;
}
@Override
public void dispose() {
// deliberately no-op
}
@Override
public boolean isDisposed() {
return true;
}
}
我们可以看到DisposableHelper这个类本身是一个枚举类,单例了一个取消订阅的Disposable。 而确认订阅是否取消了的本质,就是用当前的Disposable去和DisposableHelper.DISPOSED做对比, 如果两者不一致,那么就没有取消,如果两者一致,就代表当前订阅取消了。 而取消订阅,就是将原先的Disposable替换成DisposableHelper.DISPOSED,由于AtomicReference 涉及到了我的知识盲区,这里就不做过多赘述。
结语
以上就是Create操作符的全部内容,希望各位多多评论,多多点赞~