簡介:
這篇文章不會介紹Rxjava2的使用和操作符等內容,相信大家也或多或少有所瞭解,網上也有很多此類的文章,如果從未使用過的Rxjava或對其不怎麼了解的,可以先簡單的瞭解下Rxjava2的基本使用。
本篇文章主要是跟着源碼分析和梳理Rxjava的構建、訂閱、事件分發、線程切換等流程。
Observable的構建:
根據Rxjava的官方介紹上我們可以知道,Observable是Rxjava的5大基類之一,也是我們最常用的的被觀察者,一切的一切都要從Observable的構建開始說起。
首先我們大致的看一下Observable這個類的源碼。可以知道它是一個抽象類並且實現了ObservableSource接口。
/**
* Observable是一個抽象方法,它實現了一個ObservableSource接口
*/
public abstract class Observable<T> implements ObservableSource<T> {
......
}
/**
* ObservableSource接口只有一個抽象方法subscribe
*/
public interface ObservableSource<T> {
/**
* Subscribes the given Observer to this ObservableSource instance.
* @param observer the Observer, not null
* @throws NullPointerException if {@code observer} is null
*/
void subscribe(@NonNull Observer<? super T> observer);
}
這個ObservableSource接口,它其實只有一個需要實現的方法subscribe。很熟悉對吧,沒錯,就是Rxjava中關鍵的關鍵--訂閱方法。那麼我們來看下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;
}
}
protected abstract void subscribeActual(Observer<? super T> observer);
這裏的“observer = RxJavaPlugins.onSubscribe(this, observer);“這句我們先忽略,因爲onSubscribe方法的描述中說是一個hook方法,所以Observable中subscribe方法中只有一句重點,那就是“subscribeActual(observer);”。看最後一行我們知道在Observable類中並沒有被實現,而是作爲一個抽象方法交給了它的子類去實現具體的邏輯。
這裏我們推斷一下,因爲Observable這個類是一個抽象類,並不能創建observable實體,因此可想而知通過create、map、concat等操作符獲取的被觀察者一定是Observable的子類。是不是找一個看下代碼就知道了。
/**
* Observable類中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));
}
create操作符最終生成了一個ObservableCreate類。該類繼承了Observable並實現了subscribeActual方法。
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);
}
}
......
}
我們再來看一個map操作符。
/**
* Observable中的map方法
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
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類。該類繼承了AbstractObservableWithUpstream類,而AbstractObservable-WithUpstream類又是Observable的子類,因此ObservableMap類也實現了subscribeActual方法。
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
@Override
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)));
}
......
}
因此我們推斷出在Rxjava的鏈式調用中,直到調用訂閱方法subscribe爲止,前面的每一個節點都會生成一個新的繼承了Observable的擁有具體功能的子類。
其實這種形式類似於設計模式中的建造者(builder)模式,都是講複雜的構造過程封裝起來,通過簡單的鏈式調用完成對象的創建,只不過建造者模式中返回的是它本身,而Observable的構造過程在每一個節點都會創造出新的擁有具體功能的Observable。
subscribe訂閱過程:
前面Observable創建過程中我們提到了subscribe訂閱方法最終其實就是在最後一個節點的subscribeActual方法中被實現。這裏我們以這樣一段Rxjava代碼爲例來說明。
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(@NonNull Integer integer) throws Exception {
return "This is result " + integer;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(@NonNull String s) throws Exception {
tvShow.append("accept : "+s+"\n");
Log.e(TAG, "accept : "+s+"\n");
}
});
那麼這段代碼subscribe最終應該是執行ObservableMap類(這個類怎麼來的,前面創建過程有提到)中的subscribeActual方法。
public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends U> function;
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));
}
static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
......
}
可以看到subscribeActual方法中只有一句代碼“source.subscribe(new MapObserver<T, U>(t, function));”。不難理解,這裏的t既是我們最終new出來的Observer(例子中可以理解爲以匿名內部類出現的特殊的Observer)。那麼這裏的source又是什麼呢,看構造函數可知,source應該是在構造的時候傳遞過來的,我們找到ObservableMap創建時的代碼,也就是在Observable的map方法中。
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
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));
}
是的,通過源碼我們能夠知道source其實就是上一個節點的引用,我們這裏例子中的上一個節點就是create操作符所創建的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);
}
}
......
}
同樣的我們先關注subscribeActual方法,在這個方法中首先創建了一個CreateEmitter實例,它是一個內部類,用來過濾和分發事件(這個後面再講),我們着重關注"source.subscribe(parent);",不難看出,這裏的source是構造函數的傳參,也就是我們例子中的下面這個部分。
new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}
至此整個訂閱過程就結束了。
因此我們可以總結出:
- Rxjava的訂閱過程是一個反向的過程,由最後的節點先調用subscribeActual完成訂閱,再從後往前層層調用subscribe方法,也就是層層調用自身的subscrubeActual方法完成訂閱。
- 在每一個節點的subscrubeActual中都會創建一個Observer使之與該Observable一一對應,該Observer持有下一級Observer的引用。
事件的傳遞過程:
還是以剛剛的例子來說明,前面訂閱過程的最後的source,也就是前面代碼貼出來的部分,它是一個ObservableOnSubscribe,看這個內部類中唯一需要實現的方法subscribe,它就是事件的源頭,所有的事件都是從這裏開始的。注意它的傳參ObservableEmitter,它是一個接口。
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(@Nullable 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(@Nullable 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
*/
@NonNull
ObservableEmitter<T> serialize();
}
==================================================================================================================================================
public interface Emitter<T> {
/**
* Signal a normal value.
* @param value the value to signal, not null
*/
void onNext(@NonNull T value);
/**
* Signal a Throwable exception.
* @param error the Throwable to signal, not null
*/
void onError(@NonNull Throwable error);
/**
* Signal a completion.
*/
void onComplete();
}
這個接口很簡單,就是一些我們Rxjava中常用的方法,那麼它到底在哪裏被實現了呢?細心的你一定不難發現,在初始節點ObservableCreate的subscribeActual方法中曾創建了一個內部類的對象CreateEmitter。對,就是它實現了ObservableEmitter接口。
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());
}
}
可以看到,當調用onNext()方法時首先會判斷isDisposed(是否被棄置,Rxjava2中常用的開關)。然後在調用當前持有的Observer的onNext()方法。之前我們說過上一級節點Observer會持有下一級節點的Observer引用,所以這裏的Observer指的是下級Observer(例子中就是MapObserver)。
public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends U> function;
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));
}
static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
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) {
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);
}
......
}
}
這裏的onNext首先判斷事件是否已經結束了(調用了onError或onComplete後done爲true)。然後繼續調用actual.onNext()方法。這裏我們注意下mapper.apply(t)方法,它其實就是MapObserver用來處理數據的,說白了就是map操作符先處理完數據再傳遞給下級繼續處理。
actual是父類的屬性。當還存在下一級節點時,則是下一級的Observer引用。當已經是最下級的節點時,則爲我們new出來的Observer,也就是事件最終被處理的地方。
new Observer<Integer>() {
private int i;
private Disposable mDisposable;
@Override
public void onSubscribe(@NonNull Disposable d) {
tvShow.append("onSubscribe "+d.isDisposed()+"\n");
Log.e(TAG, "onSubscribe "+d.isDisposed()+"\n");
mDisposable = d;
}
@Override
public void onNext(@NonNull Integer integer) {
tvShow.append("onNext: value : "+integer+"\n");
Log.e(TAG, "onNext: value : "+integer+"\n");
i++;
if (i == 2) {
// 在RxJava 2.x 中,新增的Disposable可以做到切斷的操作,讓Observer觀察者不再接收上游事件
//mDisposable.dispose();
tvShow.append("onNext : isDisposable : " + mDisposable.isDisposed() + "\n");
Log.e(TAG, "onNext : isDisposable : " + mDisposable.isDisposed() + "\n");
}
}
@Override
public void onError(@NonNull Throwable e) {
tvShow.append("onError : value : " + e.getMessage() + "\n");
Log.e(TAG, "onError : value : " + e.getMessage() + "\n" );
}
@Override
public void onComplete() {
tvShow.append("onComplete" + "\n");
Log.e(TAG, "onComplete" + "\n" );
}
});
最終事件在自定義的Observer中被我們的邏輯處理和消費。
線程調度原理:
SubscribeOn
SubscribeOn作爲操作符之一,和大多數操作符一樣都會生成一個新的節點。話不多說,直接看源碼。
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
@Override
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)));
}
static final class SubscribeOnObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {
private static final long serialVersionUID = 8094547886072529208L;
final Observer<? super T> actual;
final AtomicReference<Disposable> s;
SubscribeOnObserver(Observer<? super T> actual) {
this.actual = actual;
this.s = new AtomicReference<Disposable>();
}
@Override
public void onSubscribe(Disposable s) {
DisposableHelper.setOnce(this.s, s);
}
@Override
public void onNext(T t) {
actual.onNext(t);
}
@Override
public void onError(Throwable t) {
actual.onError(t);
}
@Override
public void onComplete() {
actual.onComplete();
}
@Override
public void dispose() {
DisposableHelper.dispose(s);
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<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
}
我們會發現subscribeActual內容和其他的節點有所不同,首先它採用了觀察者中的onSubscribe方法。然後調用一次性方法設置線程調度目標。這裏重點看下scheduler.scheduleDirect方法。
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run) {
return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
w.schedule(task, delay, unit);
return task;
}
很好理解,創建一個Worker、封裝一個Runable,再將Worker和Runnable封裝成一個DisposeTask,最後用worker去執行這個task。我們來看下這個Worker到底是個啥。
@NonNull
public abstract Worker createWorker();
我們發現createWorker()方法是Scheduler的一個抽象方法,因此我們必須在Scheduler的子類中去查看具體實現。那子類又有哪些呢?
static final class SingleHolder {
static final Scheduler DEFAULT = new SingleScheduler();
}
static final class ComputationHolder {
static final Scheduler DEFAULT = new ComputationScheduler();
}
static final class IoHolder {
static final Scheduler DEFAULT = new IoScheduler();
}
static final class NewThreadHolder {
static final Scheduler DEFAULT = new NewThreadScheduler();
}
隨便找一個IoScheduler,看看createWorker的實現。
@NonNull
@Override
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
......
static final class EventLoopWorker extends Scheduler.Worker {
private final CompositeDisposable tasks;
private final CachedWorkerPool pool;
private final ThreadWorker threadWorker;
final AtomicBoolean once = new AtomicBoolean();
EventLoopWorker(CachedWorkerPool pool) {
this.pool = pool;
this.tasks = new CompositeDisposable();
this.threadWorker = pool.get();
}
......
@NonNull
@Override
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);
}
}
可以看到IoScheduler最終創建了一個EventLoopWorker,而它最終執行的schedule方法返回了“threadWorker.scheduleActual(action, delayTime, unit, tasks);“,我們繼續往下看。
@NonNull
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;
}
這裏的executor就是一個ExecutorService,這裏的submit方法,就是將callable丟到線程池中去執行任務了。那麼這個任務是什麼呢?還記得最開始的scheduler.scheduleDirect(new SubscribeTask(parent)))嘛。這個任務就是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);
}
}
run方法中代碼相信都很熟悉了,因此我們可以總結出:SubscribeOn節點在訂閱的時候,將它的上游節點的訂閱行爲,以runnable的形式扔給了一個線程池,也就是說,當訂閱流流到SubscribeOn節點時,線程發生了切換,之後流向的節點都在切換後的線程中執行。
observeOn
話不多說,同樣是上代碼。
@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<T>(observer, w, delayError, bufferSize));
}
}
首先創建一個Worker,然後在訂閱的過程中創建ObserveOnObserver並將Worker作爲參數傳遞給它,我們繼續看下這個內部類。
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, Runnable {
......
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();
}
......
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
......
}
明白了吧,其實ObserveOnObserver就是在事件傳遞的時候調用schedule()方法,進行了線程切換。我們看到schedule方法就是調用worker.schedule方法。我們前面分析了worker.schedule的參數是一個Runable,這裏是this,因此我們找到該類run()方法。
@Override
public void run() {
if (outputFused) {
drainFused();
} else {
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;
}
}
}
void drainFused() {
int missed = 1;
for (;;) {
if (cancelled) {
return;
}
boolean d = done;
Throwable ex = error;
if (!delayError && d && ex != null) {
actual.onError(error);
worker.dispose();
return;
}
actual.onNext(null);
if (d) {
ex = error;
if (ex != null) {
actual.onError(ex);
} else {
actual.onComplete();
}
worker.dispose();
return;
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
看起來很長,其實也很簡單,重點就是繼續調用onNext()將事件向下傳遞。也就是說observeOn會將它下游的onNext操作扔給它切換的線程中,因此ObserveOn影響的是它的下游節點。