Android RxJava源碼解析

在RxJava源碼分析之前,先說一下需要關注的兩個方法:onSubscribe()onSuccess()

1 Single.just()

我們會從RxJava使用的用例來切入源碼的分析。首先看一下最基本最簡單的一個RxJava使用例子 Single

Single.just("1").subscribe(new SingleObserver<String>() {
   @Override
   public void onSubscribe(Disposable d) {
       
   }

   @Override
   public void onSuccess(String s) {

   }

   @Override
   public void onError(Throwable e) {

   }
});

我們首先從 subscribe() 進入源碼分析:

Single.java

@SchedulerSupport(SchedulerSupport.NONE)
@Override
 public final void subscribe(SingleObserver<? super T> observer) {
     ObjectHelper.requireNonNull(observer, "subscriber is null");

     observer = RxJavaPlugins.onSubscribe(this, observer);

     ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null SingleObserver. Please check the handler provided to RxJavaPlugins.setOnSingleSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");

     try {
     	 // 上面都是判空沒什麼好說的,整個方法最主要的就是這個方法
         subscribeActual(observer);
     } catch (NullPointerException ex) {
         throw ex;
     } catch (Throwable ex) {
         Exceptions.throwIfFatal(ex);
         NullPointerException npe = new NullPointerException("subscribeActual failed");
         npe.initCause(ex);
         throw npe;
     }
 }

protected abstract void subscribeActual(@NonNull SingleObserver<? super T> observer);

上面分析到最主要的一個方法是 subscribeActual(),但它是一個抽象方法沒法繼續分析,所以我們要退回剛纔的例子,從操作符 just() 分析:

Signle.java

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public static <T> Single<T> just(final T item) {
	// 判空沒什麼好說的
    ObjectHelper.requireNonNull(item, "value is null");
    // RxJavaPlugins.onAssembly()其實是一個鉤子,這個方法其實會返回的SingleJust類
    return RxJavaPlugins.onAssembly(new SingleJust<T>(item));
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
public static <T> Single<T> onAssembly(@NonNull Single<T> source) {
    Function<? super Single, ? extends Single> f = onSingleAssembly;
    if (f != null) {
        return apply(f, source);
    }
    return source; // 通過debug會發現它只會返回我們傳遞的參數source,也就是SingleJust
}

------------------------------------------------------------------------------------------------
SingleJust.java

public final class SingleJust<T> extends Single<T> {

    final T value;

    public SingleJust(T value) {
        this.value = value;
    }

	// SingleJust是Single的子類,而剛纔的分析Single.subscribe()內部是調用的subscribeActual()抽象方法
	// 所以這裏就是具體的實現
    @Override
    protected void subscribeActual(SingleObserver<? super T> observer) {
    	// 參數SingleObserver是我們調用Single.subcribe(SingleObserver)傳遞進來的參數,最終就是調用回去
    	// just()是瞬時發送的,所以它沒有調用onError()
        observer.onSubscribe(Disposables.disposed());
        observer.onSuccess(value);
    }
}

public final class Disposables {
	....

	@NonNull
    public static Disposable disposed() {
        return EmptyDisposable.INSTANCE;
    }
}

public enum EmptyDisposable implements QueueDisposable<Object> {
    /**
     * Since EmptyDisposable implements QueueDisposable and is empty,
     * don't use it in tests and then signal onNext with it;
     * use Disposables.empty() instead.
     */
    INSTANCE,
    /**
     * An empty disposable that returns false for isDisposed.
     */
    NEVER
    ;

	// Disposable是可以切斷上游Observable發送事件到下游
	// 這裏的Disposable.dispose()沒有做任何事情,因爲just()一接收到就直接發送了,所以不提供也不需要切斷
    @Override
    public void dispose() {
        // no-op
    }
}

通過上面的分析,也就解析清楚這個簡單例子做的事情了。使用RxJava時,當我們調用 subscribe() 時,事件才正式開始發送。而 just() 操作符會創建一個新的 Observable,接收到數據就直接發送了。

流程圖如下:

在這裏插入圖片描述

2 Single.map()

先寫一個簡單的例子,同樣還是Single:

Single.just(1).map(new Function<Integer, String>() {
    @Override
    public String apply(Integer integer) throws Exception {
        return String.valueOf(integer);
    }
}).subscribe(new SingleObserver<String>() {
    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onSuccess(String s) {

    }

    @Override
    public void onError(Throwable e) {

    }
});

操作符 just() 上面已經分析了,我們進去分析下操作符 map(),看它是怎麼實現的數據類型轉換:

Single.java

@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Single<R> map(Function<? super T, ? extends R> mapper) {
    ObjectHelper.requireNonNull(mapper, "mapper is null");
    return RxJavaPlugins.onAssembly(new SingleMap<T, R>(this, mapper));
}

------------------------------------------------------------------------------------------------
SingleMap.java

public final class SingleMap<T, R> extends Single<R> {
    final SingleSource<? extends T> source;

    final Function<? super T, ? extends R> mapper;

    public SingleMap(SingleSource<? extends T> source, Function<? super T, ? extends R> mapper) {
        this.source = source;
        this.mapper = mapper;
    }

	// 同樣的也是在調用了Single.subscribe()的時候纔會開始發送事件
	// 這裏的source通過上面發現它是一個this,其實就是上游Observable,也就是Single.just()返回的Single子類SingleJust
	// 首先會將事件發送給上游Observable,傳遞給它一個MapSingleObserver
    @Override
    protected void subscribeActual(final SingleObserver<? super R> t) {
        source.subscribe(new MapSingleObserver<T, R>(t, mapper));
    }

    static final class MapSingleObserver<T, R> implements SingleObserver<T> {

        final SingleObserver<? super R> t;

        final Function<? super T, ? extends R> mapper;

        MapSingleObserver(SingleObserver<? super R> t, Function<? super T, ? extends R> mapper) {
            this.t = t;
            this.mapper = mapper;
        }

		// 在SingleJust調用subscribeActual()的時候,會調用這個Observer的onSubscribe()
		// 成員t是Single.subscribe(Observer)傳遞過來的,這裏沒做任何處理就直接發送
		// 參數d也是在SingleJust傳過來的,也是不做任何切斷處理
        @Override
        public void onSubscribe(Disposable d) {
            t.onSubscribe(d);
        }

		// 在SingleJust調用subscribeActual()的時候,會調用這個Observer的onSuccess()
		// 這裏的value參數是上游SingleJust接收的,在這裏通過mapper做數據類型轉換
		// mapper是我們創建的Function
        @Override
        public void onSuccess(T value) {
            R v;
            try {
                v = ObjectHelper.requireNonNull(mapper.apply(value), "The mapper function returned a null value.");
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                onError(e);
                return;
            }

            t.onSuccess(v);
        }

        @Override
        public void onError(Throwable e) {
            t.onError(e);
        }
    }
}

流程圖如下:

在這裏插入圖片描述

流程圖是從左往右看的,在 subscribe() 的時候,從左邊開始往上,然後到右邊往下的箭頭傳遞事件。

當調用 subscribe() 的時候,Observable和Observer才訂閱開始發送事件,事件會先走到 Single.map(mapper) ,然後提供一個Observer給源頭Observable,然後纔將事件往下傳遞到Observer。

3 AtomicReference

先上例子:

Observable.interval(0, 1, TimeUnit.SECONDS)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe();

上面例子是一個定時器,每秒發送一次,內部是怎麼實現的?但這裏先不講解線程切換Schedulers相關的內容,而是要講解 AtomicReference<> 這個類,方便在看其他操作符源碼的時候知道這個東西是什麼。

Observable.java

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
public static Observable<Long> interval(long initialDelay, long period, TimeUnit unit) {
	// interval()操作符已經幫我們提供了Schedulers調度器
    return interval(initialDelay, period, unit, Schedulers.computation());
} 

@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.CUSTOM)
public static Observable<Long> interval(long initialDelay, long period, TimeUnit unit, Scheduler scheduler) {
    ObjectHelper.requireNonNull(unit, "unit is null");
    ObjectHelper.requireNonNull(scheduler, "scheduler is null");

    return RxJavaPlugins.onAssembly(new ObservableInterval(Math.max(0L, initialDelay), Math.max(0L, period), unit, scheduler));
}   

------------------------------------------------------------------------------------------------
ObservableInternal.java

public final class ObservableInterval extends Observable<Long> {
    final Scheduler scheduler;
    final long initialDelay;
    final long period;
    final TimeUnit unit;

    public ObservableInterval(long initialDelay, long period, TimeUnit unit, Scheduler scheduler) {
        this.initialDelay = initialDelay;
        this.period = period;
        this.unit = unit;
        this.scheduler = scheduler;
    }

    @Override
    public void subscribeActual(Observer<? super Long> observer) {
        IntervalObserver is = new IntervalObserver(observer);
        // 提供給下游的是IntervalObserver
        // 而下面代碼is.setResource(d)將IntervalObserver這個代理指向了sch.schedulePeriodicallyDirect()這個Disposable
        // 所以下游調用Disposable.dispose()是切斷的sch.schedulePeriodicallyDirect()這個Disposable
        observer.onSubscribe(is); 

        Scheduler sch = scheduler;

        if (sch instanceof TrampolineScheduler) {
            Worker worker = sch.createWorker();
            is.setResource(worker);
            worker.schedulePeriodically(is, initialDelay, period, unit);
        } else {
        	// 一般都會走到這段代碼
            Disposable d = sch.schedulePeriodicallyDirect(is, initialDelay, period, unit);
            is.setResource(d);
        }
    }

	// 這個Observable即是一個Disposable又是一個Runnable
	// AtomicReference<Disposable>是什麼東西?怎麼繼承了它又實現了Disposable?
	// 其實它類似於一個代理,它的具體實現指向實際的那個Disposable引用,這個Disposable引用可以是自己,也可以是其他Disposable
	// AtomicReference<Disposable>指向的是上游
    static final class IntervalObserver
    extends AtomicReference<Disposable>
    implements Disposable, Runnable {

        private static final long serialVersionUID = 346773832286157679L;

        final Observer<? super Long> downstream;

        long count;

        IntervalObserver(Observer<? super Long> downstream) {
            this.downstream = downstream;
        }

		// 因爲在setResource(Disposable d)時這個AutomicReference指向的是sch.schedulePeriodicallyDirect()提供的Disposable
		// 所以調用dispose()實際是停止切斷了指向的那個Disposable,將停止事件再往下游發送
        @Override
        public void dispose() {
            DisposableHelper.dispose(this);
        }

        @Override
        public boolean isDisposed() {
            return get() == DisposableHelper.DISPOSED;
        }

		// IntervalObserver是一個Runnable
		// sch.schedulePeriodicallyDirect(is, initialDelay, period, unit)內部也是一個Executors線程池處理,會調用run()
        @Override
        public void run() {
            if (get() != DisposableHelper.DISPOSED) {
                downstream.onNext(count++);
            }
        }

		// 通過這句代碼能夠知道,這裏的Disposable是通過sch.schedulePeriodicallyDirect(is, initialDelay, period, unit)獲得
		// AtomicReference<Disposable>指向的是傳參過來的Disposable
        public void setResource(Disposable d) {
            DisposableHelper.setOnce(this, d);
        }
    }
}    

根據上面代碼分析,其實 AtomicReference<> 就是一個Disposable的代理,但是它可以指向自己,也可以指向其他Disposable,比較靈活。

4 delay()

Single.just().delay().subscribe()

Single.java

@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Single<T> delay(final long time, final TimeUnit unit, final Scheduler scheduler, boolean delayError) {
    ObjectHelper.requireNonNull(unit, "unit is null");
    ObjectHelper.requireNonNull(scheduler, "scheduler is null");
    return RxJavaPlugins.onAssembly(new SingleDelay<T>(this, time, unit, scheduler, delayError));
}

------------------------------------------------------------------------------------------------
SingleDelay.java

public final class SingleDelay<T> extends Single<T> {

    final SingleSource<? extends T> source;
    final long time;
    final TimeUnit unit;
    final Scheduler scheduler;
    final boolean delayError;

    public SingleDelay(SingleSource<? extends T> source, long time, TimeUnit unit, Scheduler scheduler, boolean delayError) {
        this.source = source;
        this.time = time;
        this.unit = unit;
        this.scheduler = scheduler;
        this.delayError = delayError;
    }

    @Override
    protected void subscribeActual(final SingleObserver<? super T> observer) {
        final SequentialDisposable sd = new SequentialDisposable();
        observer.onSubscribe(sd);
        source.subscribe(new Delay(sd, observer));
    }

	// SequentialDisposable也是AtomicReference,所以也是一個代理
    final class Delay implements SingleObserver<T> {
        private final SequentialDisposable sd;
        final SingleObserver<? super T> downstream;

        Delay(SequentialDisposable sd, SingleObserver<? super T> observer) {
            this.sd = sd;
            this.downstream = observer;
        }

		// 這裏是一個比較有意思的地方
		// 當事件未發送到下游前,這裏sd指向的是上游,也就是會切斷上游
        @Override
        public void onSubscribe(Disposable d) {
            sd.replace(d);
        }

		// 當事件發送過來後,sd重新指向了scheduler.scheduleDirect()的Disposable
		// 會切斷scheduler.scheduleDirect()的事件發送
		// 事件發送後,就和你上游沒有關係了
        @Override
        public void onSuccess(final T value) {
            sd.replace(scheduler.scheduleDirect(new OnSuccess(value), time, unit));
        }

        @Override
        public void onError(final Throwable e) {
            sd.replace(scheduler.scheduleDirect(new OnError(e), delayError ? time : 0, unit));
        }

        final class OnSuccess implements Runnable {
            private final T value;

            OnSuccess(T value) {
                this.value = value;
            }

            @Override
            public void run() {
                downstream.onSuccess(value);
            }
        }

        final class OnError implements Runnable {
            private final Throwable e;

            OnError(Throwable e) {
                this.e = e;
            }

            @Override
            public void run() {
                downstream.onError(e);
            }
        }
    }
}

6 Schedulers線程切換

6.1 subscribeOn(schedulers)

RxJava能夠一句代碼就實現線程的切換,到底怎麼實現的?這裏用 Single.subscribeOn() 來看具體的源碼。

Single.just().subscribeOn(Schedulers.newThread()).subscribe()

public final class SingleSubscribeOn<T> extends Single<T> {
    final SingleSource<? extends T> source;

    final Scheduler scheduler;

    public SingleSubscribeOn(SingleSource<? extends T> source, Scheduler scheduler) {
        this.source = source;
        this.scheduler = scheduler;
    }

    @Override
    protected void subscribeActual(final SingleObserver<? super T> observer) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer, source);
        observer.onSubscribe(parent);

		// scheduler是調用subscribeOn()傳遞的Schedulers
		// 這裏傳入的是Schedulers.newThread()
		// subscribeOn()在發生訂閱的時候就已經開始切換了線程
        Disposable f = scheduler.scheduleDirect(parent);

        parent.task.replace(f);

    }

    static final class SubscribeOnObserver<T>
    extends AtomicReference<Disposable>
    implements SingleObserver<T>, Disposable, Runnable {

        private static final long serialVersionUID = 7000911171163930287L;

        final SingleObserver<? super T> downstream;

        final SequentialDisposable task;

        final SingleSource<? extends T> source;

        SubscribeOnObserver(SingleObserver<? super T> actual, SingleSource<? extends T> source) {
            this.downstream = actual;
            this.source = source;
            this.task = new SequentialDisposable();
        }

        @Override
        public void onSubscribe(Disposable d) {
            DisposableHelper.setOnce(this, d);
        }

        @Override
        public void onSuccess(T value) {
            downstream.onSuccess(value);
        }

        @Override
        public void onError(Throwable e) {
            downstream.onError(e);
        }

        @Override
        public void dispose() {
            DisposableHelper.dispose(this); 
            task.dispose();  
        }

        @Override
        public boolean isDisposed() {
            return DisposableHelper.isDisposed(get());
        }

		// scheduler.scheduleDirect()使用Worker切換了線程
		// Worker內部最終也是使用線程池實現,這裏切了線程後,就丟給上游
        @Override
        public void run() {
            source.subscribe(this);
        }
    }

}

------------------------------------------------------------------------------------------------
Schedulers.java

@NonNull
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
	// 現在使用的是Schedulers.newThread(),這個Worker是NewThreadWorker 
    final Worker w = createWorker();

	// 一個鉤子,其實decoratedRun還是傳參的那個run
    final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

	// 它其實就是一個封裝類,主要的還是傳入的NewThreadWorker工作
    DisposeTask task = new DisposeTask(decoratedRun, w);

	// task是一個Runnable,當NewThreadWorker調用schedule()時,就將task這個Runnable丟到線程池去
	// 而task的run()其實調用的是decorateRun.run()
    w.schedule(task, delay, unit);

    return task;
}

static final class DisposeTask implements Disposable, Runnable, SchedulerRunnableIntrospection {

	...
	
    @Override
    public void run() {
        runner = Thread.currentThread();
        try {
            decoratedRun.run();
        } finally {
            dispose();
            runner = null;
        }
    }

    @Override
    public void dispose() {
        if (runner == Thread.currentThread() && w instanceof NewThreadWorker) {
            ((NewThreadWorker)w).shutdown();
        } else {
            w.dispose();
        }
    }
}

// 可以發現,RxJava切換線程最終還是使用的線程池Executor
public class NewThreadWorker extends Scheduler.Worker implements Disposable {
	private final ScheduledExecutorService executor;

	....

    @NonNull
    @Override
    public Disposable schedule(@NonNull final Runnable run) {
        return schedule(run, 0, null);
    }

    @NonNull
    @Override
    public Disposable schedule(@NonNull final Runnable action, long delayTime, @NonNull TimeUnit unit) {
        if (disposed) {
            return EmptyDisposable.INSTANCE;
        }
        return scheduleActual(action, delayTime, unit, null);
    }

	@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;
    }

	...

	// Disposable.dispose()其實就是暫停線程
	@Override
    public void dispose() {
        if (!disposed) {
            disposed = true;
            executor.shutdownNow();
        }
    }
}

流程圖如下:

在這裏插入圖片描述

從左往右看,調用 subscribeOn() 的時候做了線程切換,這裏用線程變成黃色來表示,即當 subscribe() 調用訂閱時,在 subscribeOn() 進行了線程切換,然後往後都是在切換的線程中發送事件到下游。

如果是 Single.just().subscribeOn(Schedulers.newThread()).map().subscribe(),流程圖如下:

在這裏插入圖片描述

可以看到,在 map() 操作符的時候線程還是在主線程,經過 subscribeOn() 後,發送事件都在切換的線程中執行了。

從這張圖也可以解釋一個問題,爲什麼調用多次 subscribeOn() 切換線程或者在訂閱前調用只切換一次線程。按左邊的圖,代碼順序比如 Single.just().subscribeOn().map().subscribe() 或者 Single.just().map().subscribeOn().subscribe(),最終右邊我們實際發送到下游都是在 subscribeOn() 指定的線程中運行。而 Single.just().subscribeOn().subscribeOn().map().subscrib() 總是會在第一個 subscribeOn() 指定的線程中運行。

6.2 observeOn(schedulers)

public final class SingleObserveOn<T> extends Single<T> {

    final SingleSource<T> source;

    final Scheduler scheduler;

    public SingleObserveOn(SingleSource<T> source, Scheduler scheduler) {
        this.source = source;
        this.scheduler = scheduler;
    }

    @Override
    protected void subscribeActual(final SingleObserver<? super T> observer) {
 		// 在接收到消息的時候交給了ObserveOnSingleObserver
        source.subscribe(new ObserveOnSingleObserver<T>(observer, scheduler));
    }

    static final class ObserveOnSingleObserver<T> extends AtomicReference<Disposable>
    implements SingleObserver<T>, Disposable, Runnable {
        private static final long serialVersionUID = 3528003840217436037L;

        final SingleObserver<? super T> downstream;

        final Scheduler scheduler;

        T value;
        Throwable error;

        ObserveOnSingleObserver(SingleObserver<? super T> actual, Scheduler scheduler) {
            this.downstream = actual;
            this.scheduler = scheduler;
        }

        @Override
        public void onSubscribe(Disposable d) {
        	// 在跟下游訂閱的時候還沒有切線程
            if (DisposableHelper.setOnce(this, d)) {
                downstream.onSubscribe(this);
            }
        }

        @Override
        public void onSuccess(T value) {
        	// 在接收到事件發送給下游的時候纔開始切換線程,然後在run()將事件往下傳給下游
        	// 所以ObserveOn()切換線程影響的是下游
            this.value = value;
            Disposable d = scheduler.scheduleDirect(this);
            DisposableHelper.replace(this, d);
        }

        @Override
        public void onError(Throwable e) {
            this.error = e;
            Disposable d = scheduler.scheduleDirect(this);
            DisposableHelper.replace(this, d);
        }

        @Override
        public void run() {
            Throwable ex = error;
            if (ex != null) {
                downstream.onError(ex);
            } else {
                downstream.onSuccess(value);
            }
        }

        @Override
        public void dispose() {
            DisposableHelper.dispose(this);
        }

        @Override
        public boolean isDisposed() {
            return DisposableHelper.isDisposed(get());
        }
    }
}

根據上面的分析,observeOn() 切換線程是在接收到上游事件的時候纔開始切換線程,所以它只會影響的下游的操作符線程。

流程圖如下:

在這裏插入圖片描述

發佈了199 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章