以下都是本人收集和總結的內容:
1. 什么是Rxjava
Rx含義
ReactiveX是Reactive Extensions的縮寫,一般簡寫為Rx。微軟給的定義是,Rx是一個函數庫,讓開發者可以利用可觀察序列和LINQ風格查詢操作符來編寫異步和基于事件的程序,使用Rx,開發者可以用Observables表示異步數據流,用LINQ操作符查詢異步數據流, 用Schedulers參數化異步數據流的并發處理,Rx可以這樣定義:Rx = Observables + LINQ + Schedulers。
Rxjava含義
簡單而言:RxJava就是一種用Java語言實現的響應式編程,來創建基于事件的異步程序
2. Rxjava理解與擴展(觀察者模式)
簡單概括就是,觀察者(Observer)需要在被觀察者(Observable)變化的一瞬間做出反應。
而兩者通過注冊(Register)或者訂閱(Subscribe)的方式進行綁定。
其中這個Button就是被觀察者(Observable),OnClickListener就是觀察者(Observer),兩者通過setOnClickListener達成訂閱(Subscribe)關系,之后當Button產生OnClick事件的時候,會直接發送給OnClickListener,它做出相應的響應處理。
而RxJava的觀察者模式呢,跟這個差不多,但是也有幾點差別:
- Observer與Observable是通過 subscribe() 來達成訂閱關系。
- RxJava中事件回調有三種:onNext() 、 onCompleted() 、 onError() 。
- 如果一個Observerble沒有任何的Observer,那么這個Observable是不會發出任何事件的。
關于RxJava的回調事件:
onNext():基本事件。
onCompleted(): 事件隊列完結。RxJava 不僅把每個事件單獨處理,還會把它們看做一個隊列。RxJava 規定,當不會再有新的 onNext() 發出時,需要觸發 onCompleted() 方法作為標志。
onError(): 事件隊列異常。在事件處理過程中出異常時,onError() 會被觸發,同時隊列自動終止,不允許再有事件發出。
值得注意的是在一個正確運行的事件序列中, onCompleted() 和 onError() 有且只有一個,并且是事件序列中的最后一個。如果在隊列中調用了其中一個,就不應該再調用另一個。
好了,那我們也附一張圖對比一下吧:
3. 如何實現RxJava
3.1創建Observer
在Java中,一想到要創建一個對象,我們馬上就想要new一個。沒錯,這里我們也是要new一個Observer出來,其實就是實現Observer的接口,注意String是接收參數的類型:
//創建
Observer<String> observer = new Observer<String>() {
@Override
public void onNext(String s) {
Log.i("onNext ---> ", "Item: " + s);
}
@Override
public void onCompleted() {
Log.i("onCompleted ---> ", "完成");
}
@Override
public void onError(Throwable e) {
Log.i("onError ---> ", e.toString());
}
};
當然這里也要提另外一個接口:Subscriber ,它跟Observer接口幾乎完全一樣,只是多了兩個方法,總結:
onStart(): 它會在 subscribe 剛開始,而事件還未發送之前被調用,可以用于做一些準備工作,例如數據的清零或重置。這是一個可選方法,默認情況下它的實現為空。需要注意的是,如果對準備工作的線程有要求(例如彈出一個顯示進度的對話框,這必須在主線程執行), onStart() 就不適用了,因為它總是在 subscribe 所發生的線程被調用,而不能指定線程。
unsubscribe(): 用于取消訂閱。在這個方法被調用后,Subscriber 將不再接收事件。一般在這個方法調用前,可以使用 isUnsubscribed() 先判斷一下狀態。 要在不再使用的時候盡快在合適的地方(例如 onPause() onStop() 等方法中)調用 unsubscribe() 來解除引用關系,以避免內存泄露的發生。
雖然多了兩個方法,但是基本實現方式跟Observer是一樣的,所以暫時可以不考慮兩者的區別。不過值得注意的是
實質上,在 RxJava 的 subscribe 過程中,Observer 也總是會先被轉換成一個 Subscriber 再使用。
3.2創建Observable
與Observer不同的是,Observable是通過 create() 方法來創建的。注意String是發送參數的類型:
//創建
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello");
subscriber.onNext("World");
subscriber.onCompleted();
}
});
3.3訂閱(Subscribe)
在之前,我們創建了 Observable 和 Observer ,現在就需要用 subscribe() 方法來將它們連接起來,形成一種訂閱關系:
//訂閱
observable.subscribe(observer);
這里其實確實有點奇怪,為什么是Observable(被觀察者)訂閱了Observer(觀察者)呢?其實我們想一想之前Button的點擊事件:
Button.setOnClickListener(new View.OnClickListener())
Button是被觀察者,OnClickListener是觀察者,setOnClickListener是訂閱。我們驚訝地發現,也是被觀察者訂閱了觀察者,所以應該是一種流式API的設計吧,也沒啥影響。
完整代碼如下:
//創建Observable
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello");
subscriber.onNext("World");
subscriber.onCompleted();
}
});
//創建Observe
Observer<String> observer = new Observer<String>() {
@Override
public void onNext(String s) {
Log.i("onNext ---> ", "Item: " + s);
}
@Override
public void onCompleted() {
Log.i("onCompleted ---> ", "完成");
}
@Override
public void onError(Throwable e) {
Log.i("onError ---> ", e.toString());
}
};
//訂閱
observable.subscribe(observer);
運行的結果如下,可以看到Observable中發送的String已經被Observer接收并打印了出來:
3.4線程控制——Scheduler
Scheduler是RxJava的精髓之一了。
在RxJava中,Scheduler相當于線程控制器,可以通過它來指定每一段代碼運行的線程。
RxJava已經內置了幾個Scheduler,總結:
Schedulers.immediate(): 直接在當前線程運行,相當于不指定線程。這是默認的Scheduler。
Schedulers.newThread(): 總是啟用新線程,并在新線程執行操作。
Schedulers.io(): I/O 操作(讀寫文件、讀寫數據庫、網絡信息交互等)所使用的Scheduler。行為模式和newThread()差不多,區別在于io()的內部實現是是用一個無數量上限的線程池,可以重用空閑的線程,因此多數情況下io()比newThread()更有效率。不要把計算工作放在io()中,可以避免創建不必要的線程。
Schedulers.computation(): 計算所使用的Scheduler。這個計算指的是 CPU 密集型計算,即不會被 I/O 等操作限制性能的操作,例如圖形的計算。這個Scheduler使用的固定的線程池,大小為 CPU 核數。不要把 I/O 操作放在computation()中,否則 I/O 操作的等待時間會浪費 CPU。
AndroidSchedulers.mainThread(),Android專用線程,指定操作在主線程運行。
那我們如何切換線程呢?RxJava中提供了兩個方法:subscribeOn() 和 observeOn() ,兩者的不同點在于:
subscribeOn(): 指定subscribe()訂閱所發生的線程,即 call() 執行的線程。或者叫做事件產生的線程。
observeOn(): 指定Observer所運行在的線程,即onNext()執行的線程。或者叫做事件消費的線程。
這里確實不好理解,沒關系,下面我們在具體例子中觀察現象。
//創建被觀察者
Observable.create(new Observable.OnSubscribe<Bitmap>() {
/**
* 復寫call方法
*
* @param subscriber 觀察者對象
*/
@Override
public void call(Subscriber<? super Bitmap> subscriber) {
//通過URL得到圖片的Bitmap對象
Bitmap bitmap = GetBitmapForURL.getBitmap(url);
//回調觀察者方法
subscriber.onNext(bitmap);
subscriber.onCompleted();
Log.i(" call ---> ", "運行在 " + Thread.currentThread().getName() + " 線程");
}
})
.subscribeOn(Schedulers.io()) // 指定subscribe()發生在IO線程
.observeOn(AndroidSchedulers.mainThread()) // 指定Subscriber的回調發生在UI線程
.subscribe(new Observer<Bitmap>() { //訂閱觀察者(其實是觀察者訂閱被觀察者)
@Override
public void onNext(Bitmap bitmap) {
mainImageView.setImageBitmap(bitmap);
Log.i(" onNext ---> ", "運行在 " + Thread.currentThread().getName() + " 線程");
}
@Override
public void onCompleted() {
mainProgressBar.setVisibility(View.GONE);
Log.i(" onCompleted ---> ", "完成");
}
@Override
public void onError(Throwable e) {
Log.e(" onError --->", e.toString());
}
});
現在來看一下運行的Log日志:
可以看到,call方法(事件產生)執行在IO線程,而onNext方法(事件消費)執行在main線程。說明之前分析的是對的。
3.5操作符
所謂操作符(Operators),簡單來說就是一種指令,表示需要執行什么樣的操作。Rx中的每種編程語言實現都實現了一組操作符的集合。RxJava也不例外。
RxJava中有大量的操作符,比如創建操作符、變換操作符、過濾操作符等等,這些操作符要全部講解完幾乎是不可能也沒必要的事情。所以我們只介紹常見的、有用的、重要的操作符。其他的如果用到直接到文檔查找就行了。
下面就針對前篇文章的創建(create)來說明一下另外兩種常見的創建操作符。
Observable.just()
首先給出定義:
Just操作符是創建一個將參數依次發送出來的Observable
具體一點來說就是, just() 中會接收1~9個參數,它會返回一個按照傳入參數的順序依次發送這些參數的Observable。
這樣說可能還是不夠清晰,所以畫個圖來看:
從圖中可以看出,其實就是依次發送單個數據,它的具體寫法是這樣的,非常簡單:
Observable.just("Hello","world");
//其實就相當于依次調用:
//subscriber.onNext("Hello");
//subscriber.onNext("World");
但是這里要注意一點,如果你傳遞null給just,它會返回一個發送null值的Observable,而不是返回一個空Observable(完全不發送任何數據的Observable)。后面會講到,如果需要空Observable應該使用 Empty 操作符。
現在來看完整的代碼,代碼本身很簡單,注意看Log日志:
//創建Observable
Observable.just("Hello", "World", null) .subscribe(new Observer<String>() {
@Override
public void onNext(String s) {
if (s == null) {
Log.i("onNext ---> ", "null");
}else {
Log.i("onNext ---> ", s);
}
}
@Override
public void onCompleted() {
Log.i("onCompleted ---> ", "完成");
}
@Override
public void onError(Throwable e) {
Log.i("onError ---> ", "出錯 --->" + e.toString());
}
});
這里因為我們要打印字符串,所以不能為null,我就處理了一下,可以看到當發送 null 的時候,s確實等于null。
Observable.from()
盡管與just一樣是創建操作符,但是from操作符稍微強大點。因為from操作符的作用是:
將傳入的數組或 Iterable 拆分成具體對象后,依次發送出來。
注意,這里不再是發送單個對象,而是直接發送一組對象。為了與just對比,也來畫個圖描述一下:
它的具體寫法是這樣的,也非常簡單:
String[] str = new String[]{"Hello", "World"};
//創建Observable
Observable.from(str);
4. 結合Rxjava源碼深度學習
基礎源碼
實現RxJava的代碼,這里我打上了Log日志,來看一下每個方法執行的順序。
//創建Observable
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello");
subscriber.onNext("World");
subscriber.onCompleted();
Log.i("執行順序 ---> ", " call ");
}
}).subscribe(new Observer<String>() {
@Override
public void onNext(String s) {
Log.i("onNext ---> ", s);
Log.i("執行順序 ---> ", " subscribe onNext");
}
@Override
public void onCompleted() {
Log.i("onCompleted ---> ", "完成");
Log.i("執行順序 ---> ", " subscribe onCompleted");
}
@Override
public void onError(Throwable e) {
Log.i("onError ---> ", "出錯 --->" + e.toString());
}
});
好了,來看一下Log日志:
從圖中可以看到,subscribe方法先執行,等執行完成后再執行call方法。
好了,這就是結論。先在腦子里產生個印象,方便后面追溯。
4.1 create()
進入Observable的create()方法做了些什么:
public class Observable<T> {
.....省略代碼......
static final RxJavaObservableExecutionHook hook =
RxJavaPlugins.getInstance().getObservableExecutionHook();
public static <T> Observable<T> create(OnSubscribe<T> f) {
return new Observable<T>(hook.onCreate(f));
}
.....省略代碼......
}
直接返回一個 Observable,接下里繼續看看它的構造函數:
public class Observable<T> {
.....省略代碼......
final OnSubscribe<T> onSubscribe;
protected Observable(OnSubscribe<T> f) {
this.onSubscribe = f;
}
.....省略代碼......
}
返回繼續查看 hook.onCreate(f) 。 hook 是什么鬼?
hook是一個代理對象, 僅僅用作調試的時候可以插入一些測試代碼。如單元測試
static final RxJavaObservableExecutionHook hook =
RxJavaPlugins.getInstance().getObservableExecutionHook();
繼續查看hook.onCreate(f) :
public abstract class RxJavaObservableExecutionHook {
.....省略代碼......
public <T> OnSubscribe<T> onCreate(OnSubscribe<T> f) {
return f;
}
.....省略代碼......
}
直接把OnSubscribe 這個對象返回了一下。
創建時做了三件事情:
返回了一個Observable(假設為ObservableA)
返回了一個OnSubscribe(假設為OnSubscribeA)
把返回的OnSubscribeA在ObservableA構造函數中保存為ObservableA的 .onSubscribe 屬性
create()方法創建了一個Observable,且在這個Observable中有個OnSubscribe。
所以就畫個簡圖就如下圖所示這樣:
4.2 subscribe()
subscribe() 這個是將觀察者(Observer)與被觀察者(Observable)聯系到一起的操作,也就是產生一種訂閱(Subcribe)關系。
先查看源碼:
public class Observable<T> {
.....省略代碼......
public final Subscription subscribe(final Observer<? super T> observer) {
if (observer instanceof Subscriber) {
return subscribe((Subscriber<? super T>)observer);
}
return subscribe(new Subscriber<T>() {
@Override
public void onCompleted() {
observer.onCompleted();
}
@Override
public void onError(Throwable e) {
observer.onError(e);
}
@Override
public void onNext(T t) {
observer.onNext(t);
}
});
}
.....省略代碼......
}
實質上,在 RxJava 的 subscribe 過程中,Observer 也總是會先被轉換成一個 Subscriber 再使用。
在這里就能夠看出,首先 if 中的語句意思是如果這個Observer已經是Subscriber類型,那就直接返回。如果不是的話 new了一個Subscriber ,再點進去看看:
public abstract class Subscriber<T> implements Observer<T>, Subscription {
.....省略代碼......
}
果然,它還是轉成了Subscriber類型,剛好印證了之前的話。所以為了方便起見,之后文章中,所有的觀察者(Observer)我都用Subscriber來代替。
繼續看 subscribe 源碼:
public class Observable<T> {
.....省略代碼......
static final RxJavaObservableExecutionHook hook = RxJavaPlugins.getInstance().getObservableExecutionHook();
final OnSubscribe<T> onSubscribe;
public final Subscription subscribe(Subscriber<? super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
private static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
.....省略代碼......
hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);
.....省略代碼......
}
.....省略代碼......
}
把一些暫時無關的代碼省略掉來看,其實就是執行了一句 hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber); 。
而這個 hook.onSubscribeStart 方法再點進去看看:
public <T> OnSubscribe<T> onSubscribeStart(Observable<? extends T> observableInstance, final OnSubscribe<T> onSubscribe) {
// pass through by default
return onSubscribe;
}
可以看到,竟然直接返回了一個 onSubscribe ,由于之前說過這個hook沒什么作用,直接刪掉,那就等于整個 subscribe 做了一件事就是 onSubscribe.call(subscriber) ,當然這個call里面的參數subscriber是我們代碼中傳遞進去的。
而onSubscribe在create源碼解析中我們已經知道是新建 ObservableA 的一個屬性,所以總結來說,subscribe()方法做的事情就是這樣:
ObservableA.onSubscribe.call(subscriber);
而調用 call方法,就是調用傳入的參數subscriber的onNext/onCompleted/onError方法。這就是全部的過程。依然畫個圖來說,圖中省略了create中的創建步驟:
結合圖我們最后再順一下思路:
首先創建過程也就是create()方法中創建了一個Observable,并有一個onSubscribe屬性;
其次在訂閱過程也就是subscribe()方法中,調用了create()方法中創建的Observable的onSubscribe屬性的call方法;
最后這個call回調的就是代碼中創建的Subscriber的onNext/onCompleted/onError方法。
之前Log日志可以看出,將onNext與onCompleted方法執行完后,call方法才結束。這也印證了call方法回調Subscriber的方法這一說。
4.3 map
4.3.1map使用流程
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onNext(1);
subscriber.onCompleted();
}
}).map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
return String.valueOf(integer);
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
}
});
并且回顧Observable.create過程
final OnSubscribe<T> onSubscribe;
protected Observable(OnSubscribe<T> f) {
this.onSubscribe = f;
}
public static <T> Observable<T> create(OnSubscribe<T> f) {
return new Observable<T>(hook.onCreate(f));
}
public <T> OnSubscribe<T> onCreate(OnSubscribe<T> f) {
//直接返回
return f;
}
4.3.2map源碼
這里比較神奇的地方是這個 map,其實 map 實際上做了兩件大事:
- (第一件)new 了一個 變形函數, 保存在了
OperatorMap.transform
中
查看map源碼
public class Observable<T> {
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
return lift(new OperatorMap<T, R>(func));
}
}
點擊繼續查看OperatorMap
public final class OperatorMap<T, R> implements Operator<R, T> {
final Func1<? super T, ? extends R> transformer;
public OperatorMap(Func1<? super T, ? extends R> transformer) {
this.transformer = transformer;
}
}
可以看出就是把new Func1
...省略代碼...
map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
return String.valueOf(integer);
}
...省略代碼...
保存在了transformer中去。
- (第二件)new了一個新的 Observable. 這個 Observable 的構造函數中, 傳入了一個新的 OnSubscribe. 整個
lift
函數的難點就在于這個 OnSubscribe 對象中. 我們仔細看一下它做了什么. 它其實也做了兩件大事兒:
進入lift函數
public class Observable<T> {
.....省略代碼.......
final OnSubscribe<T> onSubscribe;
protected Observable(OnSubscribe<T> f) {
this.onSubscribe = f;
}
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
//新的Observable
return new Observable<R>(new OnSubscribe<R>() {
@Override
public void call(Subscriber<? super R> o) {
try {
//hook.onLift(operator).call(o)創建了一個新的 Subscriber
//(實際上是一個 proxy)并調用了OperatorMap中的Subscriber.onNext
Subscriber<? super T> st = hook.onLift(operator).call(o);
try {
// new Subscriber created and being subscribed with so 'onStart' it
st.onStart();
onSubscribe.call(st);
} catch (Throwable e) {
// localized capture of errors rather than it skipping all operators
// and ending up in the try/catch of the subscribe method which then
// prevents onErrorResumeNext and other similar approaches to error handling
Exceptions.throwIfFatal(e);
st.onError(e);
}
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// if the lift function failed all we can do is pass the error to the final Subscriber
// as we don't have the operator available to us
o.onError(e);
}
}
});
}
.....省略代碼.......
}
繼續進入OnSubscribe.call 函數中, 看一下源碼:
public final class OperatorMap<T, R> implements Operator<R, T> {
....省略代碼.....
final Func1<? super T, ? extends R> transformer;
@Override
public Subscriber<? super T> call(final Subscriber<? super R> o) {
return new Subscriber<T>(o) {
@Override
public void onCompleted() {
o.onCompleted();
}
@Override
public void onError(Throwable e) {
o.onError(e);
}
//函數transform執行對參數t進行變形然
//后將變形結果轉發給o.onNext
@Override
public void onNext(T t) {
try {
o.onNext(transformer.call(t));
} catch (Throwable e) {
Exceptions.throwOrReport(e, this, t);
}
}
};
}
....省略代碼.....
}
hook.onLift(operator).call(o)
創建了一個新的 Subscriber (實際上是一個 proxy), 并在
Subscriber.onNext中調用
transform函數對參數
t進行變形, 然后將變形結果轉發給
o.onNext`. 這么上面的變量o是哪里的,OnSubscribe.call 調用了 4.3.1中
create
創建出來的 Observable.onSubscribe 函數!
很簡單, 該變形函數保存在了 OperatorMap.transform
中.
**總結一下 map
的行為: **
- 創建了一個新的 Observable,
- 創建了一個新的 OnSubscribe: 其中的
call
方法是整個調用鏈的關鍵. 它調用了上一級Observable.onSubscribe.call
, 同時, 還將結果通過transform
對 4.3.1處理后的結果進行變形。
3.subscribe
觸發整個回調流程. 我們來看一下主要流程
這一步也很簡單, 就是通過 Observable.subscribe
調用該對象的 Observable.onSubscribe.call
方法, 然后經過一系列調用, 最終由該對象內部臨時創建的 Subscriber 對象(上文中的 proxy 對象) 調用用戶目標 Subscriber (即代碼中 .subscribe(…)
中的參數) 的方法.
4.4 Schedulers
.subscribeOn(Schedulers.io())和.observeOn(Schedulers.computation())應用后的原理.
4.4.1基本使用
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onNext(1);
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
}
});
我們來拆解一下 .subscribeOn
和 .observeOn
的作用范圍:
-
subscribeOn
將作用于create
中的OnSubscribe.call()
方法. -
observeOn
作用于其語法中下一語句的Subscriber.onNext
等函數中.
首先分析 subscribeOn
public class Observable<T> {
public final Observable<T> subscribeOn(Scheduler scheduler) {
if (this instanceof ScalarSynchronousObservable) {
return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler);
}
//創建了一個 Observable 來轉發 OnSubscribe.call 請求
return create(new OperatorSubscribeOn<T>(this, scheduler));
}
}
與 map
一樣, 是通過創建了一個 Observable
來轉發 OnSubscribe.call
請求(代碼中的 OperatorSubscribeOn
繼承自 OnSubscribe
. 來看看具體實現
public final class OperatorSubscribeOn<T> implements OnSubscribe<T> {
final Scheduler scheduler;
final Observable<T> source;
public OperatorSubscribeOn(Observable<T> source, Scheduler scheduler) {
this.scheduler = scheduler;
this.source = source;
}
@Override
public void call(final Subscriber<? super T> subscriber) {
final Worker inner = scheduler.createWorker();
subscriber.add(inner);
//這里使用了Worker.schedule方法改變了source.call()方法執行的線程
inner.schedule(new Action0() {
@Override
public void call() {
final Thread t = Thread.currentThread();
Subscriber<T> s = new Subscriber<T>(subscriber) {
@Override
public void onNext(T t) {
subscriber.onNext(t);
}
@Override
public void onError(Throwable e) {
try {
subscriber.onError(e);
} finally {
inner.unsubscribe();
}
}
@Override
public void onCompleted() {
try {
subscriber.onCompleted();
} finally {
inner.unsubscribe();
}
}
@Override
public void setProducer(final Producer p) {
subscriber.setProducer(new Producer() {
@Override
public void request(final long n) {
if (t == Thread.currentThread()) {
p.request(n);
} else {
inner.schedule(new Action0() {
@Override
public void call() {
p.request(n);
}
});
}
}
});
}
};
source.unsafeSubscribe(s);
}
});
}
}
}
可見, 該函數中做了如下兩件事:
- 創建一個用于在不同線程執行的
Worker
對象(代碼中的 inner) - 使用上述
inner
在該對象所代表的線程中執行Observable.onSubscribe.call
方法(代碼中的source.unsafeSubscribe(s);
再來分析 observeOn
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
if (this instanceof ScalarSynchronousObservable) {
return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler);
}
//返回一個新Observable對象
return lift(new OperatorObserveOn<T>(scheduler, delayError, bufferSize));
}```
繼續查看OperatorObserveOn對象及OperatorObserveOn.call` 方法是如何生成 `st` 對象的
public final class OperatorObserveOn<T> implements Operator<T, T> {
private final Scheduler scheduler;
private final boolean delayError;
private final int bufferSize;
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) {
// avoid overhead, execute directly
return child;
} else if (scheduler instanceof TrampolineScheduler) {
// avoid overhead, execute directly
return child;
} else {
ObserveOnSubscriber<T> parent = new ObserveOnSubscriber<T>(scheduler, child, delayError, bufferSize);
parent.init();
return parent;
}
}
}
該方法會根據 `scheduler` 的類型決定返回什么樣的`Subscriber` 對象. 可見, 如果 child 類型為 `ImmediateScheduler` 或者 `TrampolineScheduler` 等以當前線程為執行環境的類型, 則直接返回 `child` 對象. 本例中, `child` 為 `NewThreadScheduler`, 因此將通過 `ObserveOnSubscriber` 對 `child` 進行包裝. 生成一個 proxy subscriber 對象.
返回來繼續查看
public class Observable<T> {
final OnSubscribe<T> onSubscribe;
//這段代碼熟悉吧
protected Observable(OnSubscribe<T> f) {
this.onSubscribe = f;
}
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
return new Observable<R>(new OnSubscribeLift<T, R>(onSubscribe, operator));
}
}
繼續查看OnSubscribeLift
```public final class OnSubscribeLift<T, R> implements OnSubscribe<R> {
static final RxJavaObservableExecutionHook hook = RxJavaPlugins.getInstance().getObservableExecutionHook();
final OnSubscribe<T> parent;
final Operator<? extends R, ? super T> operator;
public OnSubscribeLift(OnSubscribe<T> 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 = hook.onLift(operator).call(o);
try {
st.onStart();
//熟悉.....
parent.call(st);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
st.onError(e);
}
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
o.onError(e);
}
}
}
至此, 我們可以知道 observeOn
是通過以下方法對其后面的 Subscriber
進行控制的:
-
lift
->OnSubscribe.call
->proxy subscriber = new Subscriber(original subscriber)
創建了一個新的Subscriber
(實際上是個代理) - 在上述
proxy subscriber
中對original subscriber
對象的執行進行轉發. 轉發過程中,proxy subscriber
完全可以自由的控制original subscriber
執行的線程.