在上一篇文章啃源码 - RxJava(事件流的创建与接收)分析了RxJava中的事件创建与接收,上一篇我们偶然发现一个抽象的类AbstractObservableWithUpstream,我们的猜测是类似于map以及flatmap这些都操作符,是对上游事件源进行包裹、变化等相关操作那我们点到AbstractObservableWithUpstream里面看看
abstract class AbstractObservableWithUpstream<T, U> extends Observable<U> implements HasUpstreamObservableSource<T> {
/** The source consumable Observable. */
protected final ObservableSource<T> source;
/**
* Constructs the ObservableSource with the given consumable.
* @param source the consumable Observable
*/
AbstractObservableWithUpstream(ObservableSource<T> source) {
this.source = source;
}
@Override
public final ObservableSource<T> source() {
return source;
}
}
这个类接收了一个source的事件流,并实现了HasUpstreamObservableSource里面的source方法返回了包裹的source,我们看一下AbstractObservableWithUpstream的继承关系,ObservableTakeLast、ObservableDelay、ObservableMap、ObservableFlatMap等等,不知道大家有没有发现一个规律,这些类的命名与我们用到的操作符都很像,带着这个疑问那我们索性就去看一看Observable里面的map方法
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
恩,跟我们想的一样,返回了一个ObservableMap,那我们是不是可以猜测那个以操作符命名的Observable都与该操作符对应?我们也看看flatMap方法
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper,
boolean delayErrors, int maxConcurrency, int bufferSize) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
ObjectHelper.verifyPositive(maxConcurrency, "maxConcurrency");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
if (this instanceof ScalarCallable) {
@SuppressWarnings("unchecked")
T v = ((ScalarCallable<T>)this).call();
if (v == null) {
return empty();
}
return ObservableScalarXMap.scalarXMap(v, mapper);
}
return RxJavaPlugins.onAssembly(new ObservableFlatMap<T, R>(this, mapper, delayErrors, maxConcurrency, bufferSize));
}
跟进flatMap方法的调用,最终我们发现调用到此重载方法,在前面判断了一下是否是ScalarCallable,经过判断来返回empty的Observable或者 ObservableScalarXMap,如果不是ScalarCallable的话,直接就返回ObservableFlatMap,那我们先看看ObservableMap里面
public ObservableMap(ObservableSource<T> 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, U>(t, function));
}
在subscribeActual里面直接调用了source的subscribe方法,并传递了一个MapObserver,点进去
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
actual.onNext(null);
return;
}
U v;
try {
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
actual.onNext(v);
}
可以看到对事件t应用了mapper方法,再调用用actual的onNext方法,此处的actual就是我们传递进来的Observer,恩,原来map操作就是对事件运用了mapper的方法再进行发送。 RxJava中的操作符有很多,我们经常用到的线程切换也是通过类似操作符来完成的,我们一起来看一下subscribeOn
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
返回了一个ObservableSubscribeOn,继续跟进去看看
public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
不对劲!subscribeActual里面只调用了observer的onSubscribe方法,我们之前看到的其他的observable中都会去调用source的subscribe方法,我们先继续看,SubscribeTask
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
哦,原来他把订阅的调用转变成了一个Runnable了,scheduler.scheduleDirect(new SubscribeTask(parent),scheduler是我们传进来了scheduler,这里我们用IoScheduler来分析,看IoScheduler的scheduleDirect方法
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
if (tasks.isDisposed()) {
// don't schedule, we are unsubscribed
return EmptyDisposable.INSTANCE;
}
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
继续看ThreadWorder的scheduleActual方法
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
if (parent != null) {
if (!parent.add(sr)) {
return sr;
}
}
Future<?> f;
try {
if (delayTime <= 0) {
f = executor.submit((Callable<Object>)sr);
} else {
f = executor.schedule((Callable<Object>)sr, delayTime, unit);
}
sr.setFuture(f);
} catch (RejectedExecutionException ex) {
if (parent != null) {
parent.remove(sr);
}
RxJavaPlugins.onError(ex);
}
return sr;
}
上面对我们的Runnable进行了包装,最后还是通过executor来执行任务完成订阅操作以及线程的切换 趁热打铁,我们继续看一下另外一个线程切换的方法observeOn,都是一样的规律,返回了一个ObservableObserveOn,继续点进去
protected void subscribeActual(Observer<? super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
第一步判断是不是在同一个线程中执行,如果是直接订阅,如果线程不同,就专门创建了ObserveOnObserver,我们看看ObserveOnObserver里面
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();
}
继续看schedule
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
调用了worker的schedule方法,上面我们知道schedule里面完成线程切换,那我们就直接看看run方法
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
上面判断了是否还有事件,否则就调用drainNormal,我们看一下drainNormal
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue;
final Observer<? super T> a = actual;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
v = q.poll();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.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;
}
}
}
对队列进行了轮询发送事件,可以看出subscribeOn与observeOn的区别,subscribeOn是将整个事件的订阅执行线程进行切换,observeOn是对事件发送的线程进行切换