目录
RxJava是什么?
rxjava核心设计思想
RxJava使用&原理分析
基本使用
基本使用源码分析
线程切换
线程切换源码分析
RxJava变换
总结:
根据官方文档:RxJava是ReactiveX(Reactive Extensions)的Java VM实现:一个库,用于通过使用可观察序列来编写异步和基于事件的程序。
要使用RxJava,您需要创建Observables(发出数据项),以各种方式转换这些Observable以获取您感兴趣的精确数据项(通过使用Observable运算符),然后观察并响应这些有趣项目序列(通过实现观察者) 或者订阅者,然后将它们订阅到最终的变换后的Observables)。
创建被观察者
创建观察者
链接观察者和被观察者
//创建被观察者
Observable observable = Observable.create( new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
Log.d( TAG, "Observable subscribe ");
emitter.onNext( "我叫王大麻子" );
emitter.onComplete();
}
} );
//创建观察者
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.d( TAG, "Observer onSubscribe ");
}
@Override
public void onNext(String s) {
Log.d( TAG, "Observer onNext "+s);
}
@Override
public void onError(Throwable e) {
Log.d( TAG, "Observer onError ");
}
@Override
public void onComplete() {
Log.d( TAG, "Observer onComplete ");
}
};
//通过subscribe链接观察者和被观察者
observable.subscribe( observer);
输出日志:
通过日志我们知道RxJava的执行顺序是:
观察者的onSubscribe方法
被观察者的subscribe方法
观察者的onNext、onComplete或者onError
Observable
在上面的例子中我们将T限定为String,在observer中的onNext会就收到一个String 类型的对象。
Observable的crate方法
public static Observable create(ObservableOnSubscribe source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate(source));
}
@NonNull
public static Observable onAssembly(@NonNull Observable source) {
Function super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
从上面的代码我们知道create最终创建的是一个持有ObservableOnSubscribe
public final class ObservableCreate extends Observable {
final ObservableOnSubscribe source;
public ObservableCreate(ObservableOnSubscribe source) {
this.source = source;
}
@Override
protected void subscribeActual(Observer super T> observer) {
CreateEmitter parent = new CreateEmitter(observer);
//1.通知观察者订阅成功
observer.onSubscribe(parent);
try {
//2.被观察者开始进行工作 调用Emitter的onNext、onError、onComplete方法。
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
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;
}
if (!isDisposed()) {
//3.观察者接收到onNext
observer.onNext(t);
}
}
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
//3.观察者接收到onError
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 {
//3.观察者接收到onComplete
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());
}
@Override
public String toString() {
return String.format("%s{%s}", getClass().getSimpleName(), super.toString());
}
}
//省略部分内部类相关的代码
}
在被观察者调用subscribe()的时候会调用到subscribeActual方法。在这里会依次调用 注释 1,2,3。这样就完成了一次Rxjava被观察者到观察者的调用。
重点注意:
我们知道RxJava是基于扩展的的观察者模式来进行设计的,我们将这个和常规的观察者模式进行对比,来分析rxJava的设计实现。假设我们要进行一个网络请求,一般而言我们可以通过设置一个callBack对网络请求进行监听,伪代码如下:
//开始异步的网络请求
网络请求.注册监听(callBack)
发起网络请求(相关参数){
if(网络请求成功){
callBack.success(请求成功的特定数据);
}else{
callBack.failed(请求失败的特定数据);
}
}
当然上面的伪代码同样可以以链式调用的方式进行。比如在注册监听的时候返回一个网络请求对象,在调用发起网络请求。
既然观察者模式实现如此简单为什么RxJava还要设计的如此复杂呢?
个人理解原因有下:
rxjava面对的应用场景复杂,它不知道被观察者是谁,观察者是谁
rxjava需要实现链式调用,使代码阅读更加方便
被观察者需要能够灵活变化。
通过阅读源码我们发现rxJava的核心实现如下:
因为不知道具体的观察者需要什么类型的数据消息RxJava通过Observable
这里我们就不再分析其它的创建被观察者方法,因为其他的分析都是类似的去看它如何创建的。
RxJava可以利用subscribeOn()
和 observeOn()
来实现线程控制,让事件的产生和消费发生在不同的线程。
/**
* RxJava调度
* */
private void rxJavascheduling(){
//创建被观察者
Observable observable = Observable.create( new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
Log.d( TAG, "Observable subscribe 当前线程: "+Thread.currentThread().getName());
emitter.onNext( "我叫王大麻子" );
emitter.onComplete();
}
} );
//创建观察者
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.d( TAG, "Observer onSubscribe 当前线程: "+Thread.currentThread().getName());
}
@Override
public void onNext(String s) {
Log.d( TAG, "Observer onNext "+s+" 当前线程: "+Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
Log.d( TAG, "Observer onError 当前线程: "+Thread.currentThread().getName());
}
@Override
public void onComplete() {
Log.d( TAG, "Observer onComplete 当前线程: "+Thread.currentThread().getName());
}
};
//通过subscribe链接观察者和被观察者
observable.subscribeOn( Schedulers.io() ).subscribe( observer);
}
运行上面的代码结果如下:
通过运行结果我们知道:
可以看到在只指定被观察者运行所在线程的情况下,观察者和被观察者运行在相同的线程。
观察者的onSubscribe方法运行在subscribe的调用线程
在前面的基本使用源码分析里面我们已经分析了观察者和被观察者的创建过程,这里我们直接来看线程切换的源码。
public final ObservablesubscribeOn(Scheduler scheduler) { ObjectHelper.requireNonNull(scheduler, "scheduler is null"); return RxJavaPlugins.onAssembly(new ObservableSubscribeOn (this, scheduler)); }
结合基本使用的源码分析我们知道,调用subscribeOn后Observable对象转变成了一个ObservableSubscribeOn对象。这里我们不对scheduler进行详细的分析,把这个理解成一个线程池即可。
ObservableSubscribeOn实现:
public final class ObservableSubscribeOn extends AbstractObservableWithUpstream {
final Scheduler scheduler;
//source 是原来的未经变化的被观察者
public ObservableSubscribeOn(ObservableSource source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
@Override
public void subscribeActual(final Observer super T> observer) {
final SubscribeOnObserver parent = new SubscribeOnObserver(observer);
//发生在调用subscribe的线程
observer.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
static final class SubscribeOnObserver extends AtomicReference implements Observer, Disposable {
private static final long serialVersionUID = 8094547886072529208L;
final Observer super T> downstream;
final AtomicReference upstream;
SubscribeOnObserver(Observer super T> downstream) {
this.downstream = downstream;
this.upstream = new AtomicReference();
}
@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());
}
void setDisposable(Disposable d) {
DisposableHelper.setOnce(this, d);
}
}
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver parent;
SubscribeTask(SubscribeOnObserver parent) {
this.parent = parent;
}
@Override
public void run() {
//新的线程中执行source 的subscribe,对应的准备数据和onNext、onComplete或者onError执行在新线程
source.subscribe(parent);
}
}
}
通过源码我们证实了上面日志的结论。
可以看到在只指定被观察者运行所在线程的情况下,观察者和被观察者运行在相同的线程。
观察者的onSubscribe方法运行在subscribe的调用线程
接下来我们再看看RxJava如何实现观察者线程是如何指定的
public final Observable observeOn(Scheduler scheduler) {
return observeOn(scheduler, false, bufferSize());
}
public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, scheduler, delayError, bufferSize));
}
由前面的知识我们知道观察者的线程是通过ObservableObserveOn
public final class ObservableObserveOn extends AbstractObservableWithUpstream {
final Scheduler scheduler;
final boolean delayError;
final int bufferSize;
public ObservableObserveOn(ObservableSource 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) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
}
}
//相当于构建了一个观察者代理,当这个ObserveOnObserver接收到对应的数据,通过Scheduler.Worker
//来进行观察者线程的调度执行
static final class ObserveOnObserver extends BasicIntQueueDisposable
implements Observer, Runnable {
private static final long serialVersionUID = 6576896619930983584L;
final Observer super T> downstream;
final Scheduler.Worker worker;
final boolean delayError;
final int bufferSize;
SimpleQueue queue;
Disposable upstream;
Throwable error;
volatile boolean done;
volatile boolean disposed;
int sourceMode;
boolean outputFused;
ObserveOnObserver(Observer super T> actual, Scheduler.Worker worker, boolean delayError, int bufferSize) {
this.downstream = actual;
this.worker = worker;
this.delayError = delayError;
this.bufferSize = bufferSize;
}
@Override
public void onSubscribe(Disposable d) {
if (DisposableHelper.validate(this.upstream, d)) {
this.upstream = d;
if (d instanceof QueueDisposable) {
@SuppressWarnings("unchecked")
QueueDisposable qd = (QueueDisposable) d;
int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);
if (m == QueueDisposable.SYNC) {
sourceMode = m;
queue = qd;
done = true;
downstream.onSubscribe(this);
schedule();
return;
}
if (m == QueueDisposable.ASYNC) {
sourceMode = m;
queue = qd;
downstream.onSubscribe(this);
return;
}
}
queue = new SpscLinkedArrayQueue(bufferSize);
downstream.onSubscribe(this);
}
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
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;
}
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
void drainNormal() {
int missed = 1;
final SimpleQueue 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);
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
void drainFused() {
int missed = 1;
for (;;) {
if (disposed) {
return;
}
boolean d = done;
Throwable ex = error;
if (!delayError && d && ex != null) {
disposed = true;
downstream.onError(error);
worker.dispose();
return;
}
downstream.onNext(null);
if (d) {
disposed = true;
ex = error;
if (ex != null) {
downstream.onError(ex);
} else {
downstream.onComplete();
}
worker.dispose();
return;
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
@Override
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
boolean checkTerminated(boolean d, boolean empty, Observer super T> a) {
if (disposed) {
queue.clear();
return true;
}
if (d) {
Throwable e = error;
if (delayError) {
if (empty) {
disposed = true;
if (e != null) {
a.onError(e);
} else {
a.onComplete();
}
worker.dispose();
return true;
}
} else {
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;
}
@Override
public int requestFusion(int mode) {
if ((mode & ASYNC) != 0) {
outputFused = true;
return ASYNC;
}
return NONE;
}
@Nullable
@Override
public T poll() throws Exception {
return queue.poll();
}
@Override
public void clear() {
queue.clear();
}
@Override
public boolean isEmpty() {
return queue.isEmpty();
}
}
}
即指定观察者的线程执行关键在于ObservableObserveOn的静态内部类ObserveOnObserver通过它借助Scheduler.Worker进行线程调度来实现。
rxjava默认提供了几种线程池:
调度器类型 | 效果 |
---|---|
Schedulers.computation( ) | 用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量 |
Schedulers.from(executor) | 使用指定的Executor作为调度器 |
Schedulers.immediate( ) | 在当前线程立即开始执行任务 |
Schedulers.io( ) | 用于IO密集型任务,如异步阻塞IO操作,这个调度器的线程池会根据需要增长;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io( )默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器 |
Schedulers.newThread( ) | 为每个任务创建一个新线程 |
Schedulers.trampoline( ) | 当其它排队的任务完成后,在当前线程排队开始执行 |
对于变换的解释借用“
[给Android开发者的RxJava详解] http://gank.io/post/560e15be2dca930e00da1083#toc_14
”的说明:所谓变换,就是将事件序列中的对象或整个序列进行加工处理,转换成不同的事件或事件序列
map变换源码分析:
public final Observable map(Function super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap(this, mapper));
}
同样的我们来看ObservableMap的实现
public final class ObservableMap extends AbstractObservableWithUpstream {
final Function super T, ? extends U> function;
public ObservableMap(ObservableSource 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, function));
}
static final class MapObserver extends BasicFuseableObserver {
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) {
downstream.onNext(null);
return;
}
U v;
try {
//map变换的核心处理
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
downstream.onNext(v);
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public U poll() throws Exception {
T t = qd.poll();
return t != null ? ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.") : null;
}
}
}
和Rxjava的线程切换类似,ObservableMap也是通过内部实现一个特定的观察者MapObserver,在接收到消息的时候对结果进行变换。
分析到这里我决定不再对RxJava的基本使用进行分析。因为我们对它的基本设计实现已经有一个比较清晰的认识了。
结论1:Rxjava的Observer有四个回调方法
onSubscribe 当调用observable.subscribe( observer)时发生,这个方法调用于调用observable.subscribe的线程,在这里我们可以进行一些初始化工作
onNext 通知Observer有一个数据准备好了
onError 通知Observer出错
onComplete 通知完成
结论2:Rxjava的每次变化或者线程切换基本都是通过创建新的被观察者Observable的子类来实现,一般而言Observable的子类有这样的逻辑
内部实现观察者代理,在接收到对应的数据元素的时候通过这个代理对元素进行处理,在回调到最终的观察者Observer对象。
内部实现观察者代理不仅可以进行数据处理还能够决定观察者和被观察者的运行线程。
RxJava的变换和线程调度会组成被观察者链,当调用subscribe时,从当前这个observable向上调用顶层的observable的subscribe方法,然后从顶层的observable向下链式调用到当前的observable,onNext、onComplete。
因为这个结论可能有点难以理解这里在详细说明一下,任然以map变换为例:这里就不贴全部源码了,可以直接返回上面变换中来进行查看,其实核心就是在subscribe发生的时候,原来的ObservableSource 调用的是下面的代码:
public void subscribeActual(Observer super U> t) { source.subscribe(new MapObserver(t, function)); }
也就是MapObserver,这样当MapObserver的onNext、onComplete或onError被调用的时候,会经过我们指定的map变换对结果进行处理,最后在传递给真正的observer
推荐阅读:
给 Android 开发者的 RxJava 详解 http://gank.io/post/560e15be2dca930e00da1083
Rxjava中文文档:https://mcxiaoke.gitbooks.io/rxdocs/content/