demo
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("1");
emitter.onNext("2");
emitter.onNext("3");
emitter.onNext("4");
emitter.onComplete();
}
}).subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
Log.d(TAG, "s = " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.d(TAG, "完成 ");
}
});
和上一章的demo比较多了subscribeOn
和observeOn
方法,subscribeOn
表示指定被观察者执行所在线程,observeOn
用于设置执行观察者所在线程。
异步线程
被观察者和观察者异步调用
需求:在指定线程上执行被观察者并且被指定线程上执行的观察者订阅。
注:观察者的onSubscribe方法可以切断观察者与被观察者之间的事务连接关系,该方法不允许在设定的线程上执行。
架构设计
-
必须定义一个基类,责任链模式下的基类雷同,在此不表,用到那算哪!
-
定义发射器接口,三个方法分别用于:发射数据、发射完毕、发射异常;
-
定义一个观察者接口,一个订阅方法,参数为发射器:表示订阅一个发射器,使用者使用该发射器发射数据、发射完毕(异常)处理;
-
定义一个观察者接口,实现四个方法:接受上游对象数据、上游数据执行完成、上游数据执行异常、订阅(观察者也有订阅方法);
-
新建一个被观察者实例;
-
被观察者 订阅于 观察者:新建一个被观察者关联观察者类
- (1)承上:上游被观察者对象作为当前类的构造函数参数
- (2)启下:执行订阅方法,下游观察者对象作为参数
- ① 创建发射器:将下游观察者对象作为构造函数参数传递,执行发射器方法时回调下游观察者对象相应的方法;
- ② 执行下游观察者对象订阅方法;
- ③ 执行上游被观察者对象订阅方法:当前①创建的发射器被用于当前上游被观察者对象发射数据、发射完毕(异常)处理;
- 设定指定线程执行被观察者对象
- (1)承上:步骤5的类作为上游对象,通过构造函数传递给当前类
- (2)启下:执行订阅方法,传递下游观察者对象
- ① 创建一个中端观察者,将下游观察者对象作为构造函数参数传递,执行当前中端观察者时会调用下游观察者方法
- ② 调用下游观察者(同理,表示步骤6的)的订阅方法;
- ③ 指定线程执行上游对象(步骤5的类)订阅(步骤5(2))方法;
- 设定指定线程执行观察者对象
- (1)承上:步骤6的类作为上游对象,通过构造函数传递给当前类
- (2)启下:执行当前类的订阅方法,传递下游观察者对象(终端观察者)
- ① 新建一个中端观察者,传递下游观察者对象作为构造函数参数,执行当前中端观察者会调用下游观察者方法
- ② 调用上游对象订阅方法,步骤①中端观察者对象作为参数;
-
实例化一个终端观察者;
-
完成订阅。
简单理解一遍,感觉说的实在是太难了也无所谓,下面会有代码实现,代码实现仔细看,看完了再上来理解一遍。
代码实现
根据以上架构设计实现代码主体,我相信认真看一定有收获的。
-
必须定义一个基类,起到承上启下的作用。承上:上游对象-构造函数传递;启下:下游对象,执行方法时调用
//这个基类会根据下面的实际应用不断调整,添加 public abstract class Observable { //执行订阅方法 protected abstract void subscribeActual(Observer<? super T> observer); }
-
定义发射器接口,三个方法分别用于:发射数据、发射完毕、发射异常;
//发射器 public interface Emitter<T>{ //发射数据,可发射多次 public void onNext(T t); //表示发射完毕 public void onComplete(); //表示发射异常 public void onError(Throwable t); }
-
定义一个被观察者接口,一个订阅方法,参数为发射器:表示订阅一个发射器,使用者使用该发射器发射数据、发射完毕(异常)处理;
//被观察者接口 public interface ObservableOnSubscribe<T>{ //被观察者订阅一个发射器,该发射器后面会被创建,使用者使用该发射器发射数据、发射完毕、发射异常处理 void subscribe(Emitter<T> emitter) throws Exception; }
-
定义一个观察者接口,实现四个方法:接受上游对象数据、上游数据执行完成、上游数据执行异常、订阅(观察者也有订阅方法);
//定义一个观察者,观察上游信息变化 public interface Observer <T>{ //观察者订阅方法 public void onSubscribe(Disposable d); //执行数据更新 public void onNext(T t); //完成数据更新,如果当前方法执行,那么onNext将不会再被执行 public void onComplete(); //数据更新异常,如果当前方法执行,那么onNext将不会再被执行 public void onError(Throwable e); }
-
新建一个被观察者实例:被观察者订阅一个发射器,用户使用
onNext
发射器发射4条数据,并且执行onComplete
发射完成方法;ObservableOnSubscribe observableOnSubscribe = new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> emitter) throws Exception { emitter.onNext("1"); emitter.onNext("2"); emitter.onNext("3"); emitter.onNext("4"); emitter.onComplete(); } }
-
被观察者 订阅于 观察者:新建一个被观察者关联观察者类
ObservableCreate
//这个基类会根据下面的实际应用不断调整,添加 public abstract class Observable { //执行订阅方法 protected abstract void subscribeActual(Observer<? super T> observer); } //ObservableCreate继承Observable public static <T> Observable<T> create(ObservableOnSubscribe<T> source) { return new ObservableCreate<T>(source); }
-
(1)承上启下
public final class ObservableCreate<T> extends Observable<T> { //承上步骤5的被观察者实例 final ObservableOnSubscribe<T> source; public ObservableCreate(ObservableOnSubscribe<T> source) { this.source = source; } //启下:传递过来的观察者接口 @Override protected void subscribeActual(Observer<? super T> observer) { //被观察者 订阅于 下游观察者 source.subscribe(observer); }
-
设定指定线程执行被观察者对象
ObservableSubscribeOn
//这个基类会根据下面的实际应用不断调整,添加 public abstract class Observable { //执行订阅方法 protected abstract void subscribeActual(Observer<? super T> observer); //ObservableCreate继承Observable public static <T> Observable<T> create(ObservableOnSubscribe<T> source) { return new ObservableCreate<T>(source); } //ObservableSubscribeOn继承Observable public final Observable<T> subscribeOn(Scheduler scheduler) { return new ObservableSubscribeOn<T>(this, scheduler); } }
-
(1)承上启下
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> { final Scheduler scheduler; public ObservableSubscribeOn(Observable<T> source, Scheduler scheduler) { super(source); this.scheduler = scheduler; } @Override public void subscribeActual(final Observer<? super T> observer) { //上游对象 订阅于 下游观察者 source.subscribeActual(observer); } }
-
设定指定线程执行终端观察者对象
ObservableObserveOn
//这个基类会根据下面的实际应用不断调整,添加 public abstract class Observable { //执行订阅方法 protected abstract void subscribeActual(Observer<? super T> observer); //ObservableCreate继承Observable public static <T> Observable<T> create(ObservableOnSubscribe<T> source) { return new ObservableCreate<T>(source); } //ObservableSubscribeOn继承Observable public final Observable<T> subscribeOn(Scheduler scheduler) { return new ObservableSubscribeOn<T>(this, scheduler); } public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) { return new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize); } }
-
(1)承上启下
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> { final Scheduler scheduler; final boolean delayError; final int bufferSize; public ObservableObserveOn(Observable<T> source, Scheduler scheduler, boolean delayError, int bufferSize) { super(source); this.scheduler = scheduler; this.delayError = delayError; this.bufferSize = bufferSize; } @Override protected void subscribeActual(Observer<? super T> observer) { //上游对象 订阅于 下游观察者 source.subscribeActual(observer); } }
-
实例化一个终端观察者;
Observer observer = new Observer<String>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(String s) { Log.d(TAG, "s = " + s); } @Override public void onError(Throwable e) { } @Override public void onComplete() { Log.d(TAG, "完成 "); } }
-
完成订阅。
observableOnSubscribe.subscribeOn(Schedulers.io()) .observeOn(Schedulers.newThread()) .subscribeActual(observer)
以上代码是典型的责任链模式。一级级的传递最终是被观察者 订阅于 终端观察者。
接下来我们需要在设定指定线程执行被观察者对象和设定指定线程执行观察者对象创建中端观察者对象,分别用于设定被观察者执行线程 和 终端观察者执行线程
ObservableObserveOn:用于设置终端观察者执行线程
终端观察者:使用者定义的观察者对象,监听被观察者发射数据、发射完毕或者发射异常。
终端观察者总共4个方法,其中onSubscribe
方法只能和执行被观察者订阅于观察者代码在同一个线程中,接受发射数据、发射完毕和发射异常在指定线程上操作。
我们新建一个ObserveOnObserver
类:
-
继承
Observer
表示一个中端观察者,用于异步处理终端观察者; -
继承
Runnable
,表示当前是一个线程,在当前线程上操作终端观察者; -
上游对象订阅当前中端观察者,通过中端观察者线程处理终端观察者:
- (1)中端观察者通过构造函数传递终端观察者;
- (2)中端观察者实现观察者接口和线程方法,对应处理终端观察者方法(核心,自行认真摸索代码);
- (3)上游对象 订阅当前 中端观察者对象。
当前ObserveOnObserver
类是ObservableObserveOn
内部类:
以下
Scheduler.Worker
相关代码先不用管,worker.schedule(this);
理解为自行当前ObserveOnObserver
线程方法即可。
static final class ObserveOnObserver<T> implements Observer<T>, Runnable,Disposable {
Throwable error;
//用于确定是否往下接受传递的数据
volatile boolean done;
final Observer<? super T> downstream;
final Scheduler.Worker worker;
volatile boolean disposed;
//队列,用于存储上游传递过来的数据
//为什么要用队列:①保证执行顺序;②作为缓存,异步调用终端观察者时在当前缓存中获取;
SimpleQueue<T> queue;
//上游对象中的中端观察者对象
Disposable upstream;
ObserveOnObserver(Observer<? super T> actual, Scheduler.Worker worker) {
this.downstream = actual;
this.worker = worker;
}
//按照规则,该方法一定先于onNext,onComplete,onError
@Override
public void onSubscribe(Disposable d) {
if (DisposableHelper.validate(this.upstream, d)) {
this.upstream = d;
queue = new SpscLinkedArrayQueue<T>(128);
downstream.onSubscribe(this);
}
}
//相当于执行run方法
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
@Override
public void onNext(T t) {
if (done) {
return;
}
//存储到缓存队列中
queue.offer(t);
//并且执行异步操作:异步执行终端观察者方法
schedule();
}
@Override
public void onError(Throwable t) {
if (done) {
RxJavaPlugins.onError(t);
return;
}
error = t;
done = true;
schedule();
}
@Override
public void onComplete() {
if (done) {
return;
}
done = true;
schedule();
}
//表示切断与上游对象中的中端观察者联系,
@Override
public void dispose() {
if (!disposed) {
disposed = true;
upstream.dispose();
worker.dispose();
if (getAndIncrement() == 0) {
queue.clear();
}
}
}
@Override
public boolean isDisposed() {
return disposed;
}
@Override
public void run() {
drainNormal();
}
//执行终端观察者onNext还是执行onComplete或者onError
//代码写的龙飞凤舞,可以观摩
void drainNormal() {
final SimpleQueue<T> q = queue;
final Observer<? super T> a = downstream;
for(;;){
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
v = q.poll();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
disposed = true;
upstream.dispose();
q.clear();
a.onError(ex);
worker.dispose();
return;
}
boolean empty = v == null;
if (checkTerminated(d, empty, a)) {
return;
}
if (empty) {
break;
}
a.onNext(v);
}
}
}
//当前观察者接口,是否继续传递数据判断
boolean checkTerminated(boolean d, boolean empty, Observer<? super T> a) {
if (disposed) {
queue.clear();
return true;
}
if (d) {
Throwable e = error;
if (e != null) {
disposed = true;
queue.clear();
a.onError(e);
worker.dispose();
return true;
} else
if (empty) {
disposed = true;
a.onComplete();
worker.dispose();
return true;
}
}
return false;
}
}
我们再去看ObservableObserveOn
的subscribeActual
方法,当前方法执行的是上游对象订阅于当前ObserveOnObserver
中端观察者。
@Override
protected void subscribeActual(Observer<? super T> observer) {
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
ObservableSubscribeOn:用于设置被观察者执行线程
被观察者对象 订阅于 一个中端观察者对象,该中端观察者对象的作用是将被观察者在指定线程执行。
在ObservableSubscribeOn
类中定义一个SubscribeOnObserver
用于执行被观察者对象
static final class SubscribeOnObserver<T> implements Observer<T>, Disposable {
//下游对象中的中端观察者
final Observer<? super T> downstream;
//存储上游被观察者对象
final AtomicReference<Disposable> upstream;
SubscribeOnObserver(Observer<? super T> downstream) {
this.downstream = downstream;
this.upstream = new AtomicReference<Disposable>();
}
//将上游对象传递给upstream
@Override
public void onSubscribe(Disposable d) {
DisposableHelper.setOnce(this.upstream, d);
}
@Override
public void onNext(T t) {
downstream.onNext(t);
}
@Override
public void onError(Throwable t) {
downstream.onError(t);
}
@Override
public void onComplete() {
downstream.onComplete();
}
@Override
public void dispose() {
DisposableHelper.dispose(upstream);
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
以上代码没什么出奇的地方,下面新建一个线程,用于异步执行上游对象 订阅于 SubscribeOnObserver
中间观察者对象
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
所以,ObservableSubscribeOn
类的subscribeActual
方法中上游对象执行的是当前中端观察者对象
@Override
public void subscribeActual(final Observer<? super T> observer) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);
observer.onSubscribe(parent);
//相当于执行SubscribeTask的run方法
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
总结
本章核心有两个:
-
被观察者、被观察者执行线程、观察者执行线程、观察者之间形成的责任链模式;
-
被观察者执行线程、观察者执行线程巧妙的实现了线程切换,实现异步操作。