目录
目标
学习完本系列内容,主要了解一下内容:
① 初步了解RxJava2.x的使用流程;
② 探索Observable发送数据的流程;
③ 明白Observer是如何接收数据的;
④ 解析Observable和Observer如何关联的过程;
⑤ 探索RxJava线程切换的奥秘;
⑥ 了解RxJava操作符的实现原理。
1 RxJava2分发订阅流程
从一个Demo案例开始讲解:
/**观察者创建Observer**/
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG,"onSubscribe");
}
@Override
public void onNext(Object o) {
Log.e(TAG,"onNext data is >>" + o);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError data is >>" + e.toString());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
};
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext("hello");
e.onNext("RxJava2.x");
e.onComplete();
}
});
/**订阅**/
observable.subscribe(observer);
打印Log日志结果:
由Log日志可以发现,Observer的onSubscribe是最先被调用的。
RxJava的整个流程是从create开始的,我们就从create方法开始进行分析,create方法返回一个Observable对象,也就是被观察者对象,create方法需要需要传入一个ObservableOnSubscribe,首先我们先看下ObservableOnSubscribe的作用:
/**
* A functional interface that has a {@code subscribe()} method that receives
* an instance of an {@link ObservableEmitter} instance that allows pushing
* events in a cancellation-safe manner.
*
* @param <T> the value type pushed
*/
public interface ObservableOnSubscribe<T> {
/**
* Called for each Observer that subscribes.
* @param e the safe emitter instance, never null
* @throws Exception on error
*/
void subscribe(ObservableEmitter<T> e) throws Exception;
}
该接口会接收一个ObservableEmitter的一个对象,通过该对象我们可以发送消息可可以安全的取消消息,接着往里看ObservableEmitter这个接口类:
/**
* Abstraction over an RxJava {@link Observer} that allows associating
* a resource with it.
* <p>
* The onNext, onError and onComplete methods should be called
* in a sequential manner, just like the Observer's methods.
* Use {@link #serialize()} if you want to ensure this.
* The other methods are thread-safe.
*
* @param <T> the value type to emit
*/
public interface ObservableEmitter<T> extends Emitter<T> {
/**
* Sets a Disposable on this emitter; any previous Disposable
* or Cancellation will be unsubscribed/cancelled.
* @param d the disposable, null is allowed
*/
void setDisposable(Disposable d);
/**
* Sets a Cancellable on this emitter; any previous Disposable
* or Cancellation will be unsubscribed/cancelled.
* @param c the cancellable resource, null is allowed
*/
void setCancellable(Cancellable c);
/**
* Returns true if the downstream disposed the sequence.
* @return true if the downstream disposed the sequence
*/
boolean isDisposed();
/**
* Ensures that calls to onNext, onError and onComplete are properly serialized.
* @return the serialized ObservableEmitter
*/
ObservableEmitter<T> serialize();
}
ObservableEmitter是对Emitter的扩展,而扩展的方法证实了RxJava2.x引入,提供了可中途取消等新功能,继续分析Emitter:
/**
* Base interface for emitting signals in a push-fashion in various generator-like source
* operators (create, generate).
*
* @param <T> the value type emitted
*/
public interface Emitter<T> {
/**
* Signal a normal value.
* @param value the value to signal, not null
*/
void onNext(T value);
/**
* Signal a Throwable exception.
* @param error the Throwable to signal, not null
*/
void onError(Throwable error);
/**
* Signal a completion.
*/
void onComplete();
}
里面的三个方法很眼熟,到这里,我们了解传参数的数据结构,接下来继续探索create内部做了哪些操作:
@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));
}
首先对传入的source进行非空判断,我们传入ObservableOnSubscribe被用来创建ObservableCreate,ObservableCreate其实就是Observable的一个实现类。
思路捋一捋
a) Observable通过调用create创建一个Observable;
b) 调用create需要传递一个ObservableOnSubscribe类型的实例参数;
c) ObservableOnSubscribe类型的实例参数作为ObservableCreate构造函数的参数传入,一个Observable就此产生。
接下来查看ObservableCreate,首先查看ObservableCreate的两个方法:
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
@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);
}
}
source为Observable.create传入的ObservableOnSubscribe实例:
subscribeActual回调方法,它在调用Observable.subscribe时被调用,即与观察者或者被观察者发生联系时触发,subscribeActual是实现我们主要的逻辑的地方,因此比较重要,接下来我们仔细分析subscribeActual方法:
1) 首先subscribeActual传入的参数类型为Observer类型,也就是在subscribe时传入的观察者,后面会分析到;
2) 传入的Observer会被包装成一个CreateEmitter,CreateEmitter是一个继承了AtomicReference提供了原子级的控制能力,RxJava2.x提供的新特性与之息息相关,后面进行分析;
3) 观察者(observer)调用自己的observer.onSubscribe(parent);将包装后的observer传入,这也是RxJava2.x的变化,真正的鼎业是在source.subscribe(parent)这句代码执行之后开始的,而之前先调用了onSubscribe方法用来提供RxJava2.x后引入的新能力(如中断),在此处我们就能明白为何观察者的onSubscribe最先被调用了。
4) 被订阅者或者说被观察者(source)调用subscribe订阅方法与观察者发生联系,这里进行异常捕获,如果subscribe抛出了未被捕获的异常,则调用parent.onError(ex);
5) 执行subscribe时也就对应了Demo中的代码:
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext("hello");
e.onNext("RxJava2.x");
e.onComplete();
}
});
看来subscribeActual这个回调确实很重要,前面说了subscribeActual回调方法在Observable.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;
}
}
可以看到RxJavaPlugins.onSubscribe(this, observer);,我们RxJava2.0中的Hook能力就是来自这里了。然后继续看下面subscribeActual(observer);被调用了。
思路捋一捋
a) 传入的ObservableOnSubscribe最终被用来创建成ObservableCreate;
b) ObservableCreate持有我们被观察者对象以及订阅时所触发的subscribeActual;
c) 在subscribeActual中实现了我们的主要逻辑,包括observer.onSubscribe(parent);,source.subscribe(parent);,parent.onError(ex);的调用;
d) 在Observable的subscribe被调用时,开始执行事件分发流程。
2 RxJava2.x的随意取消订阅流程的原理
前面初步分析了RxJava从创建到执行的流程;
接下来我们探索RxJava2.x提供的Disposable的能力:
老规矩,先看一个Demo实例
/**观察者创建Observer**/
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG,"onSubscribe");
disposable = d;
}
@Override
public void onNext(Object o) {
Log.e(TAG,"onNext data is >>" + o);
if(o.equals("hello")){
//执行了hello之后结束
disposable.dispose();
}
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError data is >>" + e.toString());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
};
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext("hello");
Log.e(TAG,"发送了hello");
e.onNext("RxJava2.x");
Log.e(TAG,"发送了RxJava2.x");
e.onComplete();
Log.e(TAG,"发送了onComplete");
}
});
/**订阅**/
observable.subscribe(observer);
}
执行结果:
在发送完成hello之后,成功地终止了后续的Reactive流,从结果可以看出,后面的Reactive流被终止了,也就是订阅者或者说观察者接收不到了,但是被订阅者,被观察者的代码还是会执行的。
我们从disposable.dispose();方法开始入手,因为触发的该事件之后,就接收不到了,查看源码:
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();
}
回顾前面所讲的一段代码
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
@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);
}
}
- 我们之前分析在执行source.subscribe(parent);触发数据分发事件之前先执行了observer.onSubscribe(parent)这句代码,所传入的parent也就对应了我们的Disposable;
- parent是CreateEmitter类型的,但是CreateEmitter是一个实现了Disposable接口的一个类,而parent又是我们经过包装后的对象;
- 分析到这里,整理下前面的环节,根据Demo解释下:首先在执行下面代码之前:
e.onNext("hello");
Log.e(TAG,"发送了hello");
e.onNext("RxJava2.x");
Log.e(TAG,"发送了RxJava2.x");
e.onComplete();
Log.e(TAG,"发送了onComplete");
- 先执行了observer.onSubscribe(parent);在Demo中也是通过传入parent调用其dispose方法来终止Reactive流,而执行分发hello等数据的e也是我们的parent,他们都是同一个对象,而执行e.onNext("hello");中的e对象也是observer的一个包装后的ObservableEmitter类型的对象。
接下来我们查看关键点CreateEmitter parent = new CreatEmitter(observer);这个包装的过程,分析其源码:
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) {
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 (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();
}
} else {
RxJavaPlugins.onError(t);
}
}
@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<T> serialize() {
return new SerializedEmitter<T>(this);
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
CreateEmitter是ObservableCreate类的静态内部类,CreateEmitter实现了ObservableEmitter,Disposable接口类,所以需要实现其方法,这里使用了装饰者模式。
我们可以看到在ObservableEmitter内部通过Observer<? super T> observer存储了我们的observer,如此做法的目的又是什么呢?
通过查看Demo,我们在调用e.onNext("hello");时,调用的是ObservableEmitter对象的onNext方法,然后ObservableEmitter对象的onNext方法内部再通过observer调用onNext方法,但是从源码发现,并不是简单的进行调用:
@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;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
首先会判断传入的数据是否为null;
其次判断isDisposed(),如果!isDisposed()返回false,则不执行onNext();
isDisposed()什么时候会返回false?就是我们在调用了disposable.dispose()后,disposable前面分析了就是CreateEmitter parent,查看CreateEmitter.dispose()
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
里面调用了DisposableHelper.dispose(this);,我们看isDisposed()
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
RxJava的onComplete();与onError(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();
}
}
}
其内部也做了同样的判断,!isDisposed()后再决定是否执行;
我们知道onComplete()和onError(t)方法只有一个会发生,其原理也是通过isDisposed()这个方法,不管是先执行onComplete(),还是先执行onError(t),最终都会调用dispose(),而调用了dispose()以后,isDisposed()为false,就不会再去执行另外一个了,而且如果认为先调用onComplete再调用onError,onComplete不会被触发,而且会抛出NullPointerException异常。
通过以上内容我们知道了Reactive流如何被终止以及RxJava的onComplete()与onError(t),只有一个会被执行的原因;
接下来探究下DisposableHelper这个类,代码里面两个静态方法的作用:
public enum DisposableHelper implements Disposable {
DISPOSED;
public static boolean isDisposed(Disposable d) {
// 判断上次记录的终点标识的是否是 当前执行的Observer,如果是返回true
return d == DISPOSED;
}
....
public static boolean dispose(AtomicReference field) {
//1、current为我们当前的observer的Disposable的值,第一次调用时current是null
Disposable current = field.get();
//2、终止标识
Disposable d = DISPOSED;
//3、两次不相同,说明observer未调用过dispose,
if (current != d) {
//4、将终止标识的值设置給当前的observer的Disposable,并返回设置前的observer的Disposable的值,此时如果调用isDisposed(Disposable d)返回的就是ture了
current = field.getAndSet(d);
if (current != d) {
//第一次调用时会走到这里,此时current==null,返回true,
//current不为null时说明当前的observer调用了多次dispose(),而如果多次调用了Disposable的值还不是DISPOSED,说明之前设置失败,所以再次调用dispose();
if (current != null) {
current.dispose();
}
return true;
}
}
return false;
}
....
}
- DISPOSED:作为是否要终止的枚举类型的标识;
- isDisposed:判断上次记录的终点标识的是否是 当前执行的Observer,如果是返回true;
- dispose:采用了原子性引用类AtomicReference,目的是防止多线程操作出现的错误。
思路捋一捋
- 了解了RxJava的随意终止Reactive流的能力的来源;
- 明白了RxJava的onComplete();与onError(t);只有一个会被执行的秘密;
- 实现该能力的主要方式还是利用了装饰者模式;
- 我们还接触了AtomicReference这个类,在平时估计很少接触到。