我感覺Rxjava像是一條流水線,一塊原料到來經過層層加工最後交給訂閱者,當然不處理直接交給訂閱者也可以。
從基本設計(Rx1.0)來看,Observable有一個內部類實例OnSubscribe,當Observable調用subscribe時會調用這個OnSubscribe的call。這就是全部。一般來說會在call裏調用Subscriber的方法將信息傳遞過去。由此基本邏輯,又延伸封裝出各種操作符和騷操作。
線程切換和各種數據流的加工可以說是設計的核心了,實際上他們都是用lift實現的:
// 注意:這不是 lift() 的源碼,而是將源碼中與性能、兼容性、擴展性有關的代碼剔除後的核心代碼。
// 如果需要看源碼,可以去 RxJava 的 GitHub 倉庫下載。
public <R> Observable<R> lift(Operator<? extends R, ? super T> operator) {
return Observable.create(new OnSubscribe<R>() {
@Override
public void call(Subscriber subscriber) {
Subscriber newSubscriber = operator.call(subscriber);
newSubscriber.onStart();
onSubscribe.call(newSubscriber);
}
});
}
這個方法本質上是根據傳入的operator創建了新的Observable。然後我們可以想象一下,在一個鏈式調用中可以有很多次調用這個方法,最終的一個Observable調用subscribe,然後調用OnSubscribe的call,然後到上圖所示代碼裏。對call傳入的Subscriber進行處理生成新的Subscriber交給他上一級的Observable,最終交到第一個Observable,然後這個開頭開始發送數據,數據流經過一次又一次處理最終又交給真正subscribe的那個Subscriber。
1.subscribeOn在向上一級傳遞消息的時候切換線程,所以只有第一次調用有效。
observeOn在調用subscriber的方法(向下走)的時候切換線程,可以多次調用,控制下游線程。
2.線程調度分爲默認的當前線程,主線程,新線程,IO線程和計算線程。IO線程用於IO等阻塞較長時間的,計算線程則用於高密度計算類的。注意主線程是AndroidSchedulers.mainThread。interval默認在子線程。
2.取消訂閱:
Observable持有Observer的引用,所以有必要及時取消訂閱避免內存泄漏。
subscribe方法可以接收Observer和Consumer,其中因爲Consumer是隻有一個處理數據的簡單訂閱者,所以返回值爲Disposable,可以直接調用這個的dispose取消訂閱。而參數爲Observer的訂閱無返回值,這個Disposable要到Observer的OnSubscribe裏獲取。
例子1,10秒驗證碼:
首先有一個全局變量Disposable disposable,
disposable = Observable.interval(1,TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
tv.setText("還剩"+(10-aLong)+"秒");
if (aLong>=10){
disposable.dispose();
}
}
});
內部達到十秒的時候接觸訂閱,外部活動銷燬的時候也可以用這個Disposable接觸訂閱。