概述:
从最简单的RxJava的使用,来分析RxJava订阅和观察的整个流程(注:RxJava版本:2.2.7)
目标:
- RxJava中观察者和被观察者是如何联系起来的
- 被观察者(Observable)发射数据是从什么时候开始的,
- Observable的整个流程图
分析
最简单的RxJava代码如下:下面代码实现了 被观察者,发射一个1,观察者得到该发射的值并打印出来
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
emitter.onNext(1);
emitter.onComplete();
}
}).subscribe(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
Log.d("RxJava:", "onSubscribe");
}
@Override
public void onNext(Object o) {
Log.d("RxJava:", "onNext"+o.toString());
}
@Override
public void onError(Throwable e) {
Log.d("RxJava:", "onError");
}
@Override
public void onComplete() {
Log.d("RxJava:", "onComplete");
}
});
运行结果:
2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onSubscribe
2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onNext1
2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onComplete
我们首先查看 Observable.create()方法,如下:
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
//判断是否为空,如果为null 则抛出异常
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
RxJavaPlugins.onAssembly() 方法
/**
* Calls the associated hook function. 调用关联的hook方法
* @param <T> the value type
* @param source the hook's input value hook的输入值
* @return the value returned by the hook hook的返回值
*/
@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;
}
该函数是个hook函数 ,当设置hook函数的时候,会执行hook函数,默认情况下是没有设置的,即是onObservableAssembly=null,此处我们可以忽略.所以
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) 实际上返回的是new ObservableCreate<T>(source)
整个函数流程即是
new ObservableCreate<T>(source).subscribe(new Observer<Object>() {...}
ObservableCreate类:
//继承Observable
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
//缓存 ObservableOnSubscribe 这个是我们声明的
//new ObservableOnSubscribe<Object>() {
// @Override
// public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
// emitter.onNext(1);
// emitter.onComplete();
// }
//}
this.source = source;
}
//实现Observable的抽象函数 这个是重点
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
...
}
我们现在知道了 ObservableCreate是Observable的一个实现类,接下来继续走流程即是 .subscribe(new Observer<Object>(){})
,这个方法点进去是Observable的一个方法,
public abstract class Observable<T> implements ObservableSource<T> {
...
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
//observer的非空判断
ObjectHelper.requireNonNull(observer, "observer is null");
try {
//这个是和RxJavaPlugins.onAssembly()一样的hook方法 默认不走
observer = RxJavaPlugins.onSubscribe(this, observer);
//判断hook后的observer是否非空
ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");
//实际上调用的方法
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;
}
}
....
//抽象方法
protected abstract void subscribeActual(Observer<? super T> observer);
....
}
我们前面在ObservableCreate类中,看到了其实现的subscribeActual方法
//实现Observable的抽象函数 这个是重点
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
//1
observer.onSubscribe(parent);
try {
//2
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
//3
parent.onError(ex);
}
}
上述1处:调用observer的onSubscribe方法
@Override
public void onSubscribe(Disposable d) {
Log.d("RxJava:", "onSubscribe");
}
上述2处:source.subscribe(parent);
在ObservableCreate类中我们看到 source是其保存的ObservableOnSubscribe实例,即是我们在代码中实现的那个,调用.subscribe(parent)即是:
@Override
public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
emitter.onNext(1);
emitter.onComplete();
}
上述3处 当初source.subscribe的过程中出现异常便会调用 CreateEmitter的onError的方法 最后调用Observer的onNext方法
我们现在知道了 Observable.create(ObservableOnSubscribe).subscribe(Observer)
实际上是: ObservableOnSubscribe.subscribe(new CreateEmitter(Observer)) ,ObservableOnSubscribe是我们前面实现的 类 ,
我们在其subscribe方法中进行,使用CreateEmitter发射数据 并最终调用complete()方法
接下来我们看下CreateEmitter
CreateEmitter类
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) {
//缓存我们设置的观察者 Observer
this.observer = observer;
}
//该方法是我们在ObservableOnSubscribe的subscribe方法中调用的emitter.onNext(1);
@Override
public void onNext(T t) {
//先判断发射在数据是否为null
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的方法,即是最后我们回调的方法
observer.onNext(t);
}
}
//在上述3中调用的onError方法 最终调用Observer的onError方法
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
//设置hook方法 忽略
RxJavaPlugins.onError(t);
}
}
@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方法
observer.onError(t);
} finally {
dispose();
}
return true;
}
return false;
}
//同上原理 先判断是否取消订阅
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();
} finally {
dispose();
}
}
}
//存储Disposable类 用来判断是否取消了订阅
@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());
}
@Override
public String toString() {
return String.format("%s{%s}", getClass().getSimpleName(), super.toString());
}
}
上述例子的整体流程如下:
- 生成ObservableOnSubscribe实例 实现其subscribe(ObservableEmitter emitter)方法,使用emitter发射数据
- 生成ObservableCreate实例,该类实现了Observable
- Observer订阅Observable 调用ObservableCreate的subscribeActual(observer)
- 生成ObservableEmitter的实例CreateEmitter对象,调用Observer的onSubscribe的方法,
- 调用ObservableOnSubscribe的subscribe方法:即是我们上面实现的发射数据的方法
现在回答上面的两个问题:
- RxJava中观察者和被观察者在ObservableCreate实例中是通过CreateEmitter类关联起来的
- 被观察者(Observable)发射数据是在订阅后开始发射数据的 即是ObservableOnSubscribe调用subscribe方法
- Observable的整个流程图如上面分析
为了更直观的分析其整个结构 下面画出其UML类图,
上面分析以及UML类图中都指到了Disposable这个接口,该接口主要是实现判断是否取消订阅,如果取消订阅则不再执行想要的回调,我们在CreateEmitter类中也看到了相关的代码,
public interface Disposable {
/**
* Dispose the resource, the operation should be idempotent.
* 取消订阅
*/
void dispose();
/**
* Returns true if this resource has been disposed.
* @return true if this resource has been disposed
* 是否取消订阅
*/
boolean isDisposed();
}
在不同的Observable内的实现方式不同,这里不在详细说明