先來一段標準代碼分析
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
Log.e(TAG, "上游線程: " + Thread.currentThread().getName());
e.onNext("1111");
}
}).map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return 404;
}
//給上游分配多次,只會在第一次切換
}).subscribeOn(Schedulers.io())
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG, "onSubscribe: " + Thread.currentThread().getName());
}
@Override
public void onNext(Integer s) {
Log.e(TAG, "下游線程: " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
當執行.subscribeOn(Schedulers.io())的時候,這個是切換上游線程的方法
先來看一下Schedulers.io()裏面是什麼,從字面意思上看肯定是一個io線程,
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
Function<? super Scheduler, ? extends Scheduler> f = onIoHandler;
if (f == null) {
return defaultScheduler;
}
return apply(f, defaultScheduler);
}
上面二個方法返回的是一個Scheduler類,這裏暫且不討論這個類有什麼用.我們來看一下onIoScheduler這個方法,首先進來這個onIoHandler一定是空爲什麼這麼確定,我們進來RxJavaPlugins這個類裏面看,這裏面初始了很多FuncTion但是都沒有賦值,所以都爲空.所以第一次進來直接Return的是defaultScheduler這個, defaultScheduler這個又是從上面io()方法裏面傳進了個IO,IO又是什麼,
IO位於Schedules這個類裏面,是一個static final類,他裏面有個靜態代碼塊,所以一進來就爲IO初始化了,
static final Scheduler IO;
來看一下Scedulers裏面初始化的部分代碼,
public final class Schedulers {
static final Scheduler IO;
static {
IO = RxJavaPlugins.initIoScheduler(new Callable<Scheduler>() {
@Override
public Scheduler call() throws Exception {
return IoHolder.DEFAULT;
}
});
}
}
這裏我們只關注一下IO這個靜態變量,下面這行代碼就有點意思,這種寫法在ActivityService裏面獲取一個IBinder也有過,值得借鑑
RxJavaPlugins.initIoScheduler(..)在這個方法時需要傳入一個Callable接口,這個接口直接是返回傳入的泛型,就如上面代碼Callable<Scheduler>傳入的是Scheduler返回的也是Scheduler
public interface Callable<V> {
V call() throws Exception;//泛型是什麼返回的就是什麼,而返回的是交給實現類來實現
}
所以這裏我們返回的是一個IoHolder.DEFAULT,也就是直接new IoScheduler(),所以這個IO就是IoHolder
static final class IoHolder {
static final Scheduler DEFAULT = new IoScheduler();
}
public IoScheduler() {
this(WORKER_THREAD_FACTORY);
}
public IoScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
this.pool = new AtomicReference<CachedWorkerPool>(NONE);
start();
}
public void start() {
CachedWorkerPool update = new CachedWorkerPool(KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT, threadFactory);
if (!pool.compareAndSet(NONE, update)) {
update.shutdown();
}
}
最後我們再返回到最開始
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
這個IO我們已經知道了是IoHolder,所以當我們subscribeOn(Schedulers.io())的時候就是subscribeOn(IoHolder),這下我們可以分析subscribeOn這個諒
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
簡單,直接是new了一個ObservableSubscribeOn,把當前Observable和傳過來的IoHolder當個參數給傳進去,到了這裏,其實就跟之前map操作符一個樣,當我們和下游關聯的時候,就會進入到下面這個方法.
public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new Runnable() {
@Override
public void run() {
source.subscribe(parent);
}
}));
}
上面代碼可以分析出,我們的上游發射的方法 source.subscribe(parent)是在一個run()裏執行,這就如果在subscribe之前不將線程切換到主線程,那麼上游和下游都是在IO線程裏面操作.
最終會走到ObservableCreate創建操作符的下面這個方法裏
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);
}
}
而這個方法的observer將原始的observer在ObservableSubscribeOn這個被觀察者裏給替換成了他自己的SubscribeOnObserver
總結
第一步:
先是通過create方法創建了一個ObserableCreate(被觀察者)-------->通過map(轉換操作符)---->轉成被觀察者(ObserableMap)----->再通過上游的線程操作符切換成了ObservableSubscribeOn(也是被觀察者)----->再通過subscribe這個方法關聯上游和下游---->這裏會創建一個觀察者Observer
第二步
Observable.subscribe這方法裏裏,由於是了後一個被觀察者是ObservableSubscribeOn,所以流程如下
ObservableSubscribeOn.subscribeActual(Observer)---->將傳入的observer封裝成了自己的SubscribeOnObserver
----->執行Observer.onSubscribe(..)保持這個方法在原有的線程
---->ObserableMap.subscribeActual(subscribeOnObserver)--->將傳入的subscribeOnObserver封裝成MapObserver
---->ObserableCreate.subscribeActual(mapObserver)
第三步
第二步中最後到的是ObserableCreate.subscribeActual(mapObserver),這個時候是在IO線程中操作的
先是創建一個發射器CreateEmitter
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
然後
mapObserver.onSubscribe(..)--->subscribeOnObserver.onSubscribe(..)------>
在subscribeOnObserver.onSubscribe這個方法會判斷是不是已經執行過了這個方法,因爲當上遊和下游關聯的時候,如果走了線程切換會在ObservableSubscribeOn的subscribeActual方法裏執行一次,保證關聯成功的第一個方法運行在最開始的線程裏面.
----->下游的onSubscribe不在這執行
----->ObserableCreate.subscribe(parent) 把創建的發射器傳入進來
----->上游的parent.onNext("111111) 在這裏就開始發射了一個onNext事件
----->下游開始接收事件mapObserver.onNext("111111)
----->mapObserver會執行Function.apply("111111"),將"111111"轉爲404
----->subscribeOnObserver.onNext(404)
----->最後就到observer.onNext(404)
如果再執行.observeOn(AndroidSchedulers.mainThread())其實就是多了一個ObservableObserveOn觀察者
ObservableSubscribeOn SubscribeOnObserver上游線程切換,他只會影響上游的發射事件線程
ObservableObserveOn ObserveOnObserver下游線程切換,只會影響下游接收事件線程