1、基本流程分析
//完整版的被观察者
Observable.create(
//自定义的被观察者,String类型,
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
}
//订阅方法
}).subscribe(
//观察者,上流往下流向的是String类型,所以最终接收的也是String类型
new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
//一订阅就会被触发的方法
}
@Override
public void onNext(String s) {
//正常执行的回调方法
}
@Override
public void onError(Throwable e) {
//发生错误的回调方法
}
@Override
public void onComplete() {
//执行完毕触发的方法
}
});
跟踪源码之前先看下这段代码中:观察者和被观察者,被观察者是通过什么方法添加观察者,而被观察者调用什么方法通知观察者的。
观察者Observer是一个接口,它定义了几个关键方法,上面的代码已经注释了。
看起来就是通过subscribe方法,将观察者丢给被观察者(等事件触发的时候调用Observer的方法)
那么:new Observer是观察者,它的泛型是由上游流下来决定的。
public interface Observer<T> {
void onSubscribe(@NonNull Disposable d);
void onNext(@NonNull T t);
void onError(@NonNull Throwable e);
}
这一块是被观察者
Observable.create(
//自定义的被观察者,String类型,
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
}
//订阅方法
})
单纯的Observable类没有必要去看,它是一个抽象类,定义了一系列的方法,在这里你可以认为就是个工具类。
Observable.create是里面的一个静态方法。
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate(source));
}
Observable.create返回:Observable
我们刚说可以把ObseVable当成工具类,那是因为你大致看下,根本看不到什么成员变量,就定义了一堆方法,
那么为什么还返回它呢?
public abstract class Observable<T> implements ObservableSource<T>
它实现了ObservableSource
我们看下ObservableSource接口
public interface ObservableSource<T> {
void subscribe(@NonNull Observer<? super T> observer);
}
只有一个方法,Observable就是被观察者,它通过ObservableSource定义了接收观察者的方法:subscribe
关键:subscribe ,接收观察者,跟观察者模式的思想差不多,就是复杂了一些。
它的触发往下传递方法,或者说将事件源发送给观察者的方法:
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
}
//订阅方法
}
我们看下ObservableOnSubscribe接口,只有一个接口方法subscribe,接收ObservableEmitter
public interface ObservableOnSubscribe<T> {
void subscribe(@NonNull ObservableEmitter<T> e) throws Exception;
}
ObservableEmitter:中文名翻译叫被观察者发射器,从名字的意义我们大概已经有一些猜测了,
它主要定义了下列方法,CreateEmitter是它的常规实现类,另外一个是系列化实现类。
public interface ObservableEmitter<T> extends Emitter<T> {
//给当前的中断流控制器赋值
void setDisposable(@Nullable Disposable d);
//设置取消操作方法
void setCancellable(@Nullable Cancellable c);
//是否中断
boolean isDisposed();
//序列化对象(它自己)
@NonNull
ObservableEmitter<T> serialize();
//错误触发传递调用的方法
@Experimental
boolean tryOnError(@NonNull Throwable t);
}
它只有两个实现类,都在ObservableCreate:被观察者里面,是静态实现,相关代码方法里的代码我们后面涉及到会贴出来,其实大概作用从方法名字大家都能猜出来。
我们从代码上就可以确认触发源是:e.onNext(“A”);
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
}
}
在subscribe里面的触发源逻辑是我们可以自己来定义掌握的。
到这里总结:Observable.create创建了ObservableCreate,实现了Observable->实现了ObservableSource
关键是:ObservableSource里面的subscribe方法,接收观察者,那么观察者怎么被它接收进来呢?
再看下最初的代码:
//完整版的被观察者
Observable.create(
//自定义的被观察者,String类型,
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
}
//订阅方法
}).subscribe(
//观察者,上流往下流向的是String类型,所以最终接收的也是String类型
new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
//一订阅就会被触发的方法
}
@Override
public void onNext(String s) {
//正常执行的回调方法
}
@Override
public void onError(Throwable e) {
//发生错误的回调方法
}
@Override
public void onComplete() {
//执行完毕触发的方法
}
});
Observable.create == Observable=被观察者-》实现了ObservableSource接口,该接口定义了接收观察者的subscribe方法。
观察者Observer是一个接口,具体的实现是我们实现的,这个也是最简单。
那么关键就是这个订阅方法了:.subscribe,它是Observable里面的一个方法我们跟踪进去源码看关键代码
源码:
@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));
}
RxJavaPlugins.onAssembly是一个全局钩子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;
}
其中f是null,所以这块代码正常执行是接收一个source返回一个source,没有做任何事情,如果我们实例化创建一个hook,秉承着不破坏规则的原则,接收一个source返回一个source,中间我们可以监听全局的对应的被观察者的创建情形,大概就是这样一个意思,其实没什么用,我们可以不用关注它,接下来我们继续看new ObservableCreate(source),肯定返回一个ObservableCreate对象,也就是ObservableCreate.subscribe(观察者),我们跟进看一下subscribe方法
@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);
} 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;
}
}
subscribeActual(observer);,subscribeActual的代码实现在ObservableCreate
跟着关键代码走:
protected abstract void subscribeActual(Observer<? super T> observer);
里面是一个抽象类,那么谁调用它就谁实现它,我们看一下ObservableCreate的subscribeActual方法
@Override
protected void subscribeActual(Observer<? super T> observer) {
//首先将我们自定义的观察者丢到发射器里面 包裹了一层,包裹这东西我们放在后面分析
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
//接着调用观察者的onSubscribe方法,也就是一订阅就执行观察的onSubscribe,打个问号,有何意义?
observer.onSubscribe(parent);
try {
//最终使用自定义被观察者调用subscribe方法接收
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
来到这里解决了我们上面的疑问,也就是如何接收观察者的:
创建了一个发射器 CreateEmitter parent = new CreateEmitter(observer);
被observer持有 observer.onSubscribe(parent);
这个source就是我们一开始创建的那个:
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
}
}
我们创建了发射器,并调用了发射器的onNext方法,从这里开始往下传递,并决定一开始的流的泛型。
关键核心点:在Rxjava源码里面你会看到每一层的链式调用最终都会有这个代码:source.subscribe(parent);,我们看代码都是从最里面往外面看,最里面也就是观察者Observer,一层一层包裹往上传递就是通过这个代码实现的,source是上一层调用者,也就是被观察者Observable,
直到最上一层CreateEmitter,我们一开始的创建自定义被观察者里面也决定了你要传递事件源进来,并决定它往下传递的事件的泛型。
总结:
Observable.create =(是它的父类) Observable (被观察者),实现了ObservableSource,定义了接收观察的subscribe方法
create方法接收一个ObservableOnSubscribe,,并在它的subscribe方法里面接收一个发射器,并调用了发射器的onNext方法开始发送事件源,并决定往下传递事件的泛型类型。
new Observer 观察者:需要我们自己创建,并接收上游往下传递的信息。
Rxjava的观察者模式,因为链式调用,观察者通过source.subscribe(parent);将我们的观察者通过subscribe往上一层传递,最终到达顶层的被观察者里面的发射器,往下调用onNext方法。
下面给一张简单的订阅流程图:
这是完整版的流程图,感觉还不如上面那张。
4、加入map操作符学习它的流程
代码如下:
//完整版的被观察者
Observable.create(
//自定义的被观察者,String类型,
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
}
//订阅方法
})
//ObservableCreate.map
.map(new Function<String, Bitmap>() {
@Override
public Bitmap apply(String s) throws Exception {
return null;
}
})
//ObservableMap.subscribe
.subscribe(
//观察者,上流往下流向的是String类型,所以最终接收的也是String类型
new Observer<Bitmap>() {
@Override
public void onSubscribe(Disposable d) {
//一订阅就会被触发的方法
}
@Override
public void onNext(Bitmap b) {
//正常执行的回调方法
}
@Override
public void onError(Throwable e) {
//发生错误的回调方法
}
@Override
public void onComplete() {
//执行完毕触发的方法
}
});
加入了map操作符之后,谁调用被观察者?进入map源码我们看到是ObservableMap调用了subscribe
我们从上面的学习知道了subscribe方法是被观察者接收观察者的方法,不用看也知道ObservableMap实现了Observable,它也是一个被观察者。因为map是Observable里面的方法,返回值也是Observable。
关键是我们要知道操作符的本质,它干了什么?
我们还是跟上面一样的分析流程,链式调用我们一般都是从最里面开始分析,观察者还是一样没变,我们还是继续分析subscribe方法,还是跟上面一样,subscribeActual方法,谁调用我谁实现它。
public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends U> function;
public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
//持有上一层的对象被观察者
super(source);
this.function = function;
}
@Override
public void subscribeActual(Observer<? super U> t) {
//被观察者调用订阅方法将对象往上传递
source.subscribe(new MapObserver<T, U>(t, function));
}
跟着关键代码走:source.subscribe(new MapObserver<T, U>(t, function)); 其中source就是上一层的调用者,通过构造函数传递进来的,我们再看new MapObserver<T, U>(t, function)
Function:
public interface Function<T, R> {
R apply(@NonNull T t) throws Exception;
}
也是我们实现的map里面的方法,接着我们看下MapObserver
关键代码
static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
final Function<? super T, ? extends U> mapper;
MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
super(actual);
this.mapper = mapper;
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
actual.onNext(null);
return;
}
U v;
try {
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
actual.onNext(v);
}
首先看一下t也就是我们的观察者或者说终点在这个类中会做什么,先赋值:super(actual);持有了上一层被观察者,和持有我们实现的map的实现类:function
最终的发射器会调用onNext方法往下传递,我们要看它的onNext方法
try {
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
actual.onNext(v);
先调用function的实现方法,再调用原本的对象的onNext方法: actual.onNext(v);
在map操作符中我们将观察者或者说是终点包裹了一层:MapObserver,然后通过subscribe方法扔给上一层的调用者,我们已经知道一个调用subscribe方法应该怎么走了,无非就是找上一层调用者的subscribeActual实现方法,在这里上一层是我们的自定义被观察者
@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);
}
}
还是之前的流程,将接收的对象扔进发射器里面,调用观察者的subscribe方法,然后通过自定义的source调用onSubscribe,这个source是起点或者说源头事件源。
还是之前的思路:在发射器的onNext方法里面,如果没有被中断,那么会调用observer.onNext(t);这个t就是我们自定义被观察者的时候丢进去的事件源。此时这个oberver就是MapObserver,而刚才我们已经知道MapObserver的onNext方法先执行了function的转换方法,然后将得到的返回对象传递给下一层的onNext,最后来到我们的终点。
画图表示:
总结:基本的订阅跟发布流程,是将终点或者说是自定义的观察者通过subscribe方法扔给上一层,上一层的subscribeActual方法会先包裹一层,如果是源头,也就是自定义被观察者的话包裹的那层叫做发射器,我们在实现被观察者的时候会调用发射器的onNext方法,这个方法会调用下一层的包裹的onNext方法,如果是操作符的话,在调用下一层的onNext方法之前会调用操作法的function,之后将得到的返回对象传递给下一层的onNext。
操作符就是创建一个观察者,对原来的观察者包裹了一层,在执行到对应的onNext方法前,先执行对应的操作符方法,之后再根据是什么操作符执行什么逻辑。
从观察者开始跟进,它是一层一层往上传递,每传递一层则添加了一层包裹,直到最上游,被观察者包裹了一层发射器,之后通过onNext一层一层拆包调用。
画图表示:
如何是多个map:
我们弄懂了map,其实其他操作符也是差不多一样的操作,核心就是封包和拆包,往上封包传递和往下拆包调用。
Rxjava的流程就是:观察者通过source.subscribe(parent);将我们的观察者通过subscribe往上一层传递,最终到达顶层的被观察者里面的发射器,往下调用onNext方法,当然在往上传递前会先给自己包裹一层包裹。
从观察者开始,它是一层一层往上传递,每传递一层则有添加了一层包裹,直到最上游,被观察者包裹了一层发射器,之后通过onNext一层一层拆包调用。
这就是Rxjava的封包和拆包。