RxJava已经用了很长一段时间了,从刚开始的迷迷糊糊observable,observer,subscriber傻傻搞不清楚,到后面会使用、用的顺手,一直到研究源码,过程也有点缓慢。不可置疑,RxJava是一个强大大大大的框架,熟悉了它的流式编程后,可以极大的简化你的代码复杂度。
本文主要解读RxJava的源码,不会探讨操作符的使用,不过作为举例,会带大家进入源码看observerOn()操作符的Java实现。
本文可以分为两个部分:
1、最简单的订阅事件
2、observerOn(AndroidScheduler.main())是怎么实现线程切换的
所以我们要明确源码中以下代码的调用而不是把源码从头看完
Observable.create(
new Observable.OnSubscribe() {
@Override
public void call(Subscriber super Integer> subscriber) {
subscriber.onNext(1);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber1);
subscriber1 = new Subscriber(){...}
1.1 Observable.create()
把observeOn()暂时忽略掉,也就是看看Observable.create()和Observable.subscribe()
//Observable.java
final OnSubscribe onSubscribe;
protected Observable(OnSubscribe f) {
this.onSubscribe = f;
}
public static Observable create(OnSubscribe f) {
return new Observable(RxJavaHooks.onCreate(f));
}
create方法是一个静态方法,就像他的名字,就是new一个Observable对象,不可谓不简单。create方法接收的参数是OnSubscribe,熟悉的朋友都知道,OnSubscribe接口继承自Action1,也就是有个接受一个参数无返回的call方法:
//Action1.java
public interface Action1 extends Action {
void call(T t);
}
那么回到上面create,RxJavaHooks.onCreate(f)又对OnSubscribe做了什么呢?
//RxJavaHooks.java
//这是成员变量
onObservableCreate = new Func1() {
@Override
public Observable.OnSubscribe call(Observable.OnSubscribe f) {
//获得Observeable的执行Hook,今后observable的onCreate等类似生命周期的回调都会通知此Hook
return RxJavaPlugins.getInstance().getObservableExecutionHook().onCreate(f);
}
};
public static Observable.OnSubscribe onCreate(Observable.OnSubscribe onSubscribe) {
Func1 f = onObservableCreate;
if (f != null) {
//简单的调用了onObservableCreate的call方法,call方法实现在上面
return f.call(onSubscribe);
}
return onSubscribe;
}
//RxJavaPlugins.java
private final AtomicReference observableExecutionHook = new AtomicReference();
public RxJavaObservableExecutionHook getObservableExecutionHook() {
if (observableExecutionHook.get() == null) {
//看看系统中有没有该实现
Object impl = getPluginImplementationViaProperty(RxJavaObservableExecutionHook.class, System.getProperties());
if (impl == null) {
//使用默认实现
observableExecutionHook.compareAndSet(null, RxJavaObservableExecutionHookDefault.getInstance());
} else {
observableExecutionHook.compareAndSet(null, (RxJavaObservableExecutionHook) impl);
}
}
return observableExecutionHook.get();
}
RxJavaHooks中对onSubscribe参数没有做什么实质的操作,只是类似一个总控制台,告诉他自身的RxJavaObservableExecutionHook对象一个observale已经create,而RxJavaObservableExecutionHook的默认实现中的onCreate是空实现,这里我们就不看了。
回到Observable.create()方法,也就是调用了构造函数,然后对this.onSubscribe赋值。到此Observable.create就走完了。
1.2 subscribe()
subscribe中做的是其实也特别简单,就是有异常就调用try catch然后丢给onError,没有就调用之前create时传入的onSubscribe的call()方法。subscribe最终调用的是Observable中的一个静态方法:
static Subscription subscribe(Subscriber super T> subscriber, Observable observable) {
if (subscriber == null) {
throw new IllegalArgumentException("subscriber can not be null");
}
if (observable.onSubscribe == null) {
throw new IllegalStateException("onSubscribe function can not be null.");
}
//onStart就是在这里调用的
subscriber.onStart();
......
try {
//约等于observable.onSubscribe.call(subscriber),call方法就是在这里被调用的
RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
return RxJavaHooks.onObservableReturn(subscriber);
} catch (Throwable e) {
......
try {
subscriber.onError(RxJavaHooks.onObservableError(e));
} catch (Throwable e2) {
......
throw r; // NOPMD
}
}
return Subscriptions.unsubscribed();
}
}
在这里可以看到onStart最先在当前线程调用,紧接着try to call
observable.onSubscribe.call(subscriber)
这里的subscriber就是我们调用subscribe(Subscriber)传入的参数,如果出现异常就调用subscriber.onError().所以在onSubscribe中的call方法中调用的诸如Subscriber.onNext等也都是在这个时候执行的。
2.1observerOn的实现
回到最初的代码中,看看.observeOn(AndroidSchedulers.mainThread())方法里干了什么事。
//Observable.java
public final Observable observeOn(Scheduler scheduler) {
return observeOn(scheduler, RxRingBuffer.SIZE);
}
//最终调用
public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
if (this instanceof ScalarSynchronousObservable) {
return ((ScalarSynchronousObservable)this).scalarScheduleOn(scheduler);
}
return lift(new OperatorObserveOn(scheduler, delayError, bufferSize));
}
public final Observable lift(final Operator extends R, ? super T> operator) {
return create(new OnSubscribeLift(onSubscribe, operator));
}
这里有个lift方法,顾名思义就是转换的方法了。这个lift方法内部需要两样东西,一个是旧的onSubscribe(可以看成create时候new的那个)和一个opterator,然后它用这两个变量,去new出一个新的OnSubscribe丢给了create方法,那么目前我们可以断定,RxJava的转换操作都是经过lift方法来实现的,再lift方法内部,它重新调用create方法以旧的onSubscribe为参数产生一个新的Onservable对象,可以简单粗暴地理解为RxJava中你用过了n次lift方法(操作符其实都是用这个方法实现的),那么最终在整个过程中产生过n+1个Observable对象。那么好像秘密都在OnSubscribeLife这个类中了,看看它的实现:
public final class OnSubscribeLift implements OnSubscribe {
final OnSubscribe parent;
final Operator extends R, ? super T> operator;
public OnSubscribeLift(OnSubscribe parent, Operator extends R, ? super T> operator) {
this.parent = parent;
this.operator = operator;
}
@Override
public void call(Subscriber super R> o) {
try {
Subscriber super T> st = RxJavaHooks.onObservableLift(operator).call(o);
try {
st.onStart();
parent.call(st);
} catch (Throwable e) {
......
}
} catch (Throwable e) {
......
}
}
}
它把传入的旧的onSubscribe对象当成parent,在call调用的时候会先执行operator.call(Subscriber)得到一个新的Subscriber,如果按照我们文章开头贴出的那段简单代码中的调用,此时传入call的Subscriber其实就是subscriber1。那么我们在这里先暂定subscriber1为旧的subscriber,operator.call返回的st为新的subscriber,然后parent是第一次create时候new的OnSubscriber对象。先看看operator.call做了什么,那么我们应该去看lift方法传入的OperatorObserveOn的实现:
public final class OperatorObserveOn implements Operator {
private final Scheduler scheduler;
public OperatorObserveOn(Scheduler scheduler, boolean delayError, int bufferSize) {
this.scheduler = scheduler;
this.delayError = delayError;
this.bufferSize = (bufferSize > 0) ? bufferSize : RxRingBuffer.SIZE;
}
@Override
public Subscriber super T> call(Subscriber super T> child) {
if (scheduler instanceof ImmediateScheduler) {
return child;//直接返回不做什么
} else if (scheduler instanceof TrampolineScheduler) {
return child;//直接返回不做什么
} else {
//剩余情况返回了一个ObserveOnSubscriber对象,下看面可以知道它继承自Subscriber,
//而且new出来之后调了init就直接返回了,那么我们应该看看它的init
//由于它是一个Subscriber,我们还需要看它的onNext等实现
ObserveOnSubscriber parent = new ObserveOnSubscriber(scheduler, child, delayError, bufferSize);
parent.init();
return parent;
}
}
static final class ObserveOnSubscriber extends Subscriber implements Action0 {
final Queue
上面我们讲过ObserveOnSubscriber被new出来后直接被返回,那么作为一个Subscriber,外部肯定会调用它的onNext方法来传递数据的,那么,正如我们所想的,onNext方法中每传入一个t,都会调用Queue.offer,如果成功进入schedule()调度,而在schedule方法中调用的是Scheduler.Worker.schedule()。这是个abstract方法,那么它在哪里实现呢?
2.2 AndroidSchedulers.mainThread()
这时候终于轮到它出面了,看看mainThread()方法:
public final class AndroidSchedulers {
private static final AndroidSchedulers INSTANCE = new AndroidSchedulers();
private final Scheduler mainThreadScheduler;
private AndroidSchedulers() {
RxAndroidSchedulersHook hook = RxAndroidPlugins.getInstance().getSchedulersHook();
Scheduler main = hook.getMainThreadScheduler();
if (main != null) {
mainThreadScheduler = main;
} else {
mainThreadScheduler = new LooperScheduler(Looper.getMainLooper());//获得UI线程Loop
}
}
public static Scheduler mainThread() {
return INSTANCE.mainThreadScheduler;
}
class LooperScheduler extends Scheduler {
private final Handler handler;
LooperScheduler(Looper looper) {
handler = new Handler(looper);
}
@Override
public Worker createWorker() {
return new HandlerWorker(handler);
}
static class HandlerWorker extends Worker {
private final Handler handler;
HandlerWorker(Handler handler) {
this.handler = handler;
this.hook = RxAndroidPlugins.getInstance().getSchedulersHook();
}
@Override
public Subscription schedule(Action0 action, long delayTime, TimeUnit unit) {
if (unsubscribed) {
return Subscriptions.unsubscribed();
}
action = hook.onSchedule(action);
ScheduledAction scheduledAction = new ScheduledAction(action, handler);
Message message = Message.obtain(handler, scheduledAction);
message.obj = this; // Used as token for unsubscription operation.
handler.sendMessageDelayed(message, unit.toMillis(delayTime));
if (unsubscribed) {
handler.removeCallbacks(scheduledAction);
return Subscriptions.unsubscribed();
}
return scheduledAction;
}
@Override
public Subscription schedule(final Action0 action) {
return schedule(action, 0, TimeUnit.MILLISECONDS);
}
}
static final class ScheduledAction implements Runnable, Subscription {
private final Action0 action;
ScheduledAction(Action0 action, Handler handler) {
this.action = action;
this.handler = handler;
}
@Override public void run() {
try {
action.call();
} catch (Throwable e) {
......
}
}
在AndroidSchedule.mainThread()方法中,LooperScheduler的构造函数的参数是Loop.getMainLooper(),那么之前我们说的Scheduler.Worker.schedule()这个方法,就是LooperScheduler中的静态内部类HandlerWorker所实现的schedule()方法了,这个方法中把一个Runnbale Message丢给了handler,那么该Runable就会在handler所在的线程调用,而该Runnable中的run实现是调用了action0.call(),也就是前面看的ObserveOnSubscriber对象它实现的call方法,回过头去看,ObserveOnSubscriber.call调用了childSubscriber.onNext那这个childSubscriber是什么呢?
public final class OnSubscribeLift implements OnSubscribe {
@Override
public void call(Subscriber super R> o) {
Subscriber super T> st = RxJavaHooks.onObservableLift(operator).call(o);
}
}
没错,childSubscriber就是上面的对象o,也就是lift操作之后的subscriber,这也就是为什么我们说observerOn()调用后,下面写的所有map也好,subscribe也好,所有的onNext方法都在observerOn()指定的线程里调用。
总结
RxJava的流式编程最大的功臣非lift莫属了,但是他的实现非常简单,这给了我们很大的自定义operator的空间,不过就目前的操作符来看,基本需求都能覆盖了,所以自定义operator其实不是很建议的。RxJava的流式编程,其实就是基于java的函数回调OnSubscribe.call()方法,就比如文中的最简单的例子,create()的时候产生了一个onSubscribe1,observerOn()内部产生了onSubscribe2,最后在subscribe的时候,调用流程是这样的:
onSubscribe2.call(){//对比与示例中observerOn产生的
onSubscribe1.call(){//对比与示例中create产生的
//还有onSubscribe0等等。假设!!!,跟示例无关了。
onSubscribe0.call(){
//这是最开始create的onSubscribe,不是OnSubscribeLift
doSomething
}
doSomething
}
doSomething
}
这就是RxJava的响应式编程.