目录
一、概述
二、观察者模式
三、Rxjava2简单使用
四、源码分析
1、创建被观察者
2、创建观察者
3、subscribe()
五、总结
Rxjava2作为一个异步操作库,在进行耗时任务时,给我们提供了非常方便的、逻辑简洁的操作。这篇文章咱们来仔细分析Rxjava2的源码,了解它内部的实现原理。
说明:本文分析的Rxjava2版本为2.1.9。
在分析Rxjava2源码之前,咱们先来看Rxjava2中的一个核心设计模式:观察者模式。
所谓观察者模式,就是A对象对B对象的数据非常敏感,当B对象的数据改变时,A对象马上做出响应,这就是观察者模式,此时B对象为被观察者,A对象则为观察者。在Android开发中经常遇到这种情况:发送网络请求获取数据,当数据成功返回时,UI马上进行更新显示该数据,这也是一种观察者模式。而Rxjava2框架,就是采用观察者模式。
...
private void rxjavaTest(){
//1.创建被观察者
Observable observable =Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
System.out.println("开始发射数据1");
emitter.onNext("发射数据1");
System.out.println("开始发射数据2");
emitter.onNext("发射数据2");
}
});
//2.创建观察者
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Object o) {
System.out.println("接收到数据:" + o);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
};
//3.被观察者订阅观察者
observable.subscribe(observer);
}
...
代码执行后的打印结果:
开始发射数据1
接收到数据:发射数据1
开始发射数据2
接收到数据:发射数据2
这里需要说明一下,在普通的观察者模式中,是观察者订阅被观察者,从而将两者关联起来。但是在Rxjava2中,也就是举例的第3步中是被观察者订阅了观察者,这样做是为了方便开发者采用链式调用的方式使用Rxjava2,不必过于纠结。关于Rxjava2的链式调用,咱们后面分析。
首先来看看被观察者Observable类:
public abstract class Observable implements ObservableSource {
...
}
这是一个抽象类,实现自ObservableSource。
在上面栗子中:
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
}
});
可以看到,创建被观察者调用的是Observable类的create方法,并需要传入一个ObservableOnSubscribe实例对象,跟进去看create方法:
...
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static Observable create(ObservableOnSubscribe source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate(source));
}
...
该方法首行是负责验证参数是否为空并抛出空指针异常,咱们需要注意的是第二行代码:
return RxJavaPlugins.onAssembly(new ObservableCreate(source));
这行代码表示返回一个RxJavaPlugins.onAssembly的值,这个值就是一个Observable实例对象,看传入的参数类:
public final class ObservableCreate extends Observable {
final ObservableOnSubscribe source;
public ObservableCreate(ObservableOnSubscribe source) {
this.source = source;
}
...
}
可以看到ObservableCreate实现了Observable接口,至于ObservableCreate类内部的具体逻辑,暂时先不用管。RxJavaPlugins.onAssembly()方法中传入了一个ObservableCreate实例对象,接着看RxJavaPlugins.onAssembly():
...
@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
public static Observable onAssembly(@NonNull Observable source) {
Function super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
...
这是一个hook实现,关于hook,可以理解为这是一个抽象代理,这个代理默认情况下不会对咱们的形参Observable做任何的处理,但是如果开发者想要对Observable做处理,可以调用RxJavaPlugins的SetonObservableAssembly()设置开发者自己实现的代理,从而替换原Observable,最后真正返回的是Observable的实现类ObservableCreate类的实例对象。在这里咱们没做任何处理,所以返回默认的Observable实现类ObservableCreate。至此创建完了一个被观察者对象Observable。
先来看Observer:
public interface Observer {
void onSubscribe(@NonNull Disposable d);
void onNext(@NonNull T t);
void onError(@NonNull Throwable e);
void onComplete();
}
看到Observer是一个接口,内部实现也很简单,提供了几个暴露给开发者的接口方法。
现在看上面栗子中创建观察者的方式:
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Object o) {
System.out.println("接收到数据:" + o);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
};
直接new了一个Observerz接口对象。基本整个创建被观察者的过程都很好理解。
这个方法就是被观察者订阅观察者的调用方法,栗子中的实现是:
observable.subscribe(observer);
来看subscribe的代码:
public abstract class Observable implements ObservableSource {
...
@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");
//具体的订阅实现方法,该方法为Observable类的抽象方法,具体实现在其子类
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
...
}
ObjectHelper.requireNonNull(observer, "observer is null")和RxJavaPlugins.onSubscribe(this, observer)这两个方法和创建被观察者时候一样的功能,分别负责验空和代理。咱们看主要的代码subscribeActual(observer),该方法为Observable类的抽象方法,具体实现在其子类,也就是ObservableCreate类:
public final class ObservableCreate extends Observable {
...
@Override
protected void subscribeActual(Observer super T> observer) {
//事件发射器的创建类,相当于发射器的适配器
CreateEmitter parent = new CreateEmitter(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
...
}
CreateEmitter是ObservableCreate的内部类,用于适配被观察者中的事件发射器,最后的数据操作将交给这个类来处理。observer.onSubscribe(parent)作用是将该发射器类和观察者产生订阅关系,两者关联起来。
source.subscribe(parent)中source就是在创建被观察者对象时传入的ObservableOnSubscribe对象实例,调用其subscribe方法,将上游事件发送对象(ObservableOnSubscribe)和下游接收对象(Observer)关联起来。
在上面的栗子中,ObservableOnSubscribe即:
new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
System.out.println("开始发射数据1");
emitter.onNext("发射数据1");
System.out.println("开始发射数据2");
emitter.onNext("发射数据2");
}
});
Observer又订阅了parent,即CreateEmitter,所以最后上游发射的事件将交由CreateEmitter处理:
static final class CreateEmitter
extends AtomicReference
implements ObservableEmitter, 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) {
//对发射事件做非空判断
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
//如果isDisposed为false,就将事件交由观察者对象,在这里就是咱们代码中new的observer对象
if (!isDisposed()) {
observer.onNext(t);
}
}
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
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(t);
} finally {
dispose();
}
return true;
}
return false;
}
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.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 serialize() {
return new SerializedEmitter(this);
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
如果isDisposed为false,就将事件交由观察者对象,在这里就是咱们代码中new的observer对象。
至此最简单的Rxjava2流程分析完成,可以看到逻辑还是很简单清晰的,当然代码量肯定不止咱们分析的这么点,还是那句话,看源码要抓住主干,将流程弄清楚,就简单了。
上面代码不涉及到RxJava2的操作符,也没使用到RxJava2的线程控制,这样使用RxJava2框架是没有灵魂的,因此咱们接下来将代码升级。在接下来第二篇分析RxJava2框架源码的文章里,咱们将讲解RxJava2中的操作符和线程调度,传送门:RxJava2源码分析(下):操作符和线程调度https://blog.csdn.net/qq_29152241/article/details/82598506
关注我的博客和github,有大量福利哟~
csdn博客:https://blog.csdn.net/qq_29152241
github:https://github.com/cozing