【RxJava】- 變換操作符源碼分析
【RxJava】- 過濾操作符源碼分析
【RxJava】- 結合操作符源碼分析
【RxJava】- 連接操作符源碼分析
簡介
一個在 Java VM 上使用可觀測的序列來組成異步的、基于事件的程序的庫。簡單一點就是創建一個事件,注冊一個觀察者,當事件發生改變時,及時通知觀察者。同時RxJava可以把一序列的異步事件按照一定規則組合成新的事件序列。
RxAndroid里面就幾個類,是在RxJava基礎上針對Android開發封裝了一些使用方法而已。
參考
GitHub:RxJava
GitHub:RxAndroid
ReactiveX:reactivex
中文文檔地址:ReactiveX/RxJava文檔中文版
版本
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
訂閱
- subscribe(@NonNull Observer<? super T> observer)
執行被觀察者subscribeActual方法并傳入觀察者實例。
調度器
下面將大體介紹一下RaJava里面的調度器(Scheduler)。Schedulers類用于返回標準Scheduler實例的靜態工廠方法。
Observable
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) { return apply(f, source);}
return source;
}
下面基本都是在變量“f”等于null情況下分析。
Creating Observables
創建操作
create
返回ObservableCreate實例
Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
try {
if (!emitter.isDisposed()) {
for (int i = 1; i < 5; i++) {emitter.onNext(i);}
emitter.onComplete();
}
} catch (Exception e) {
emitter.onError(e);
}}.subscribe(new Observer<Integer>() {...}
看一下create方法
public static <T> Observable<T> create(@NonNull ObservableOnSubscribe<T> source) {
Objects.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<>(source));
}
看一下onAssembly方法
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
onObservableAssembly默認是null,所以create最終返回的是持有被觀察者的source(ObservableCreate類型)。
然后調用ObservableCreate對象的subscribe方法,并傳入觀察者實例,在subscribe方法中繼續調用ObservableCreate的subscribeActual方法并傳入觀察者實例observer。
看一下subscribeActual方法做了什么
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
創建事件發射器CreateEmitter并傳入觀察者實例observer,調用onSubscribe方法,通知觀察者,觀察關系已經準備好,并傳入事件發射器,以便觀察者可以主動選擇放棄對事件通知的接受。
在被觀察者中,通過調用CreateEmitter中的onNext,onError,onComplete等方法,如果事件觀察沒有被取消,那么會調用觀察者(observer)中對應的方法來通知觀察者。
-
發射器
在ObservableCreate有那個發射器,CreateEmitter和SerializedEmitter,一般的發射器和序列發射器。SerializedEmitter維護了一個隊列數組,保證有序的調用onNext, onError 和 onComplete,調用onNext時,會把傳入的值插入到隊列,然后循環從隊列獲取,然后執行觀察者的onNext方法。
至于有序調用,我查看源碼后,我的理解是這樣的:有序指的是在執行完所以隊列里面的事件(即隊列全部值都被取出并通知觀察者),然后才會執行onError或者onComplete方法,onError和onComplete只有其中一個方法被執行了,另一個不會再被執行。
如果執行了onError和onComplete其中一個,那么剩余隊列里面的事件將不會被執行。
當調用onError時異常為ExceptionHelper.TERMINATED時,觀察者的onError不會被調用,更多請直接查看源碼。
defer
返回ObservableDefer實例
延期創建被觀察者對象,直到有觀察者訂閱時才創建Observable,并且為每個觀察者創建一個新的Observable。
調用defer傳入的實例(Supplier類型)的get()方法,獲取被觀察者對象(ObservableSource類型)
Observable.defer((Supplier<ObservableSource<Integer>>) () -> observer -> observer.onNext(1)).subscribe(...)
具體的可以看一下ObservableDefer這個類,至于subscribe方法怎么傳參數,大致看一下調用邏輯就明白了。
Empty/Never/Throw
Empty
返回ObservableEmpty實例,創建一個不發射任何數據,但是正常終止的Observable,會調用觀察者onSubscribe和onComplete方法Never
返回ObservableNever實例,創建一個不發射數據也不終止的Observable,調用觀察者onSubscribe方法。-
Throw
用error方法實現,返回ObservableError實例,參數為持有異常實例的JustValue實例。創建一個不發射數據以一個錯誤終止的Observable,調用觀察者onSubscribe和onError方法。
From
數據轉換,實現有:fromAction,fromArray,fromCallable,fromCompletable,fromFuture,fromFuture,fromIterable,fromMaybe,fromPublisher,fromRunnable,fromSingle,fromSupplier。對應Observable實現請自己查看源碼,里面代碼不多,閱讀完基本知道怎么用。
Interval
創建一個按固定時間間隔發射整數序列的Observable,返回ObservableInterval實例,同時會默認傳入一個ComputationScheduler實例作為調度器。從0開始自加,每發射一次加1。
interval(long initialDelay, long period, @NonNull TimeUnit unit, @NonNull Scheduler scheduler)
- initialDelay
延遲發射第一個值,即“0”,后面按period間隔時間正常發射。 - period
兩次發射直接的間隔時間 - unit
initialDelay和period時間單位 - scheduler
調度器
如果想在主線程接收事件,需要用observeOn(AndroidSchedulers.mainThread())轉換。AndroidSchedulers就是RxAndroid里面的類了。
Just
創建一個發射指定值的Observable,可以傳入多個參數,如果傳入一個參數返回ObservableJust實例,多個返回ObservableFromArray實例,前者把傳入的一個參數原封不動發射后就完成,后者需要把數組中的數據一個一個原封不動發射后完成,前者完成可以看成是后者的一種特殊情況。
Range
創建一個發射特定整數序列的Observable,參數如果是int返回ObservableRange實例,如果是long返回ObservableRangeLong實例。
這個和上面的interval差不多,不同的interval從0開始,如果不取消,就一直發射,而Range只發射自定參數范圍的整數,發射完就停止,發射一次自加1。比如range(1,3)將收到1,2,3.
Repeat
創建一個發射特定數據重復多次的Observable,返回ObservableRepeat實例。比如對just操作做重復操作:
Observable.just(1,3).repeat().subscribe(...)
repeat可接收一個參數用作重復次數。
-
repeatUntil
返回ObservableRepeatUntil實例,需要傳入BooleanSupplier類型參數。每個操作完成后都會調用ObservableRepeatUntil中的onComplete方法,而在該方法中又會調用BooleanSupplier的getAsBoolean方法來判斷是否需要再次執行操作,如果不需要者操作終止。
-
repeatWhen
返回ObservableRepeatUntil實例,需要傳入Function類型參數。有條件的重新訂閱和發射原來的Observable。比如:Observable.just("A", "B").repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() { @Override public ObservableSource<?> apply(Observable<Object> objectObservable) throws Exception { return Observable.timer(10000, TimeUnit.MILLISECONDS); } }).subscribe(new Consumer<String>() {...}
代碼中設置了下次執行的時間是10秒之后,這種方式只能執行兩次
Start
返回一個Observable,它發射一個類似于函數聲明的值。
Timer
創建一個Observable,它在一個給定的延遲后發射一個特殊的值,返回ObservableTimer實例。
Transforming Observables
轉換操作
Buffer
Observable.create(emitter -> {}).buffer(1)
定期收集Observable的數據放進一個數據包裹,然后發射這些數據包裹,而不是一次發射一個值。
-
ObservableBuffer
buffer(int count),buffer(int count, int skip) buffer(int count, @NonNull Supplier<U> bufferSupplier) buffer(int count, int skip, @NonNull Supplier<U> bufferSupplier)
都返回ObservableBuffer實例,bufferSupplier默認ArrayListSupplier實例。
Observable.create((ObservableOnSubscribe<Integer>) emitter -> { for (int i = 0 ; i < 10 ; i++){ emitter.onNext(i); } }).buffer(5).subscribe(...)
當count == skip時,收集數據策略由BufferExactObserver完成,當count != skip由BufferSkipObserver完成。
BufferExactObserver
當buffer收集的數據到達count時發射一次-
BufferSkipObserver
就有點意思了,BufferSkipObserver中有個隊列數組buffers,每采集一次數據時,當if (index++ % skip == 0)時,會創建一個新的數據收集數組,然后放到buffers中。然后遍歷buffers中的數據,并將數據放入數據收集數組里面,當前一個數據收集數組收集到的數據個數等于count便會發射一次通知觀察者,然后從buffers移除這個數據收集數組,如果buffers還存在數據收集數組,那么接下來的數據便會插到這個數組中。
-
ObservableBufferTimed
buffer(long timespan, long timeskip, @NonNull TimeUnit unit) buffer(long timespan, long timeskip, @NonNull TimeUnit unit, @NonNull Scheduler scheduler) buffer(long timespan, @NonNull TimeUnit unit) buffer(long timespan, @NonNull TimeUnit unit, int count) buffer(long timespan, @NonNull TimeUnit unit, @NonNull Scheduler scheduler, int count)
都返回ObservableBufferTimed實例,bufferSupplier默認ArrayListSupplier實例。
- 當timespan == timeskip && maxSize == Integer.MAX_VALUE,收集策略BufferExactUnboundedObserver完成。
- timespan == timeskip,BufferExactBoundedObserver完成。
- 其它情況BufferSkipBoundedObserver完成。
定期以List的形式發射新的數據,采集數據的時候會把數據放到集合中,達到count停止收集,當間隔時間達到timespan或者timeskip時候,發射一次數據,具體算法可以查看上面收集策略實現類。
ObservableBufferBoundary
不貼方法了,自己看源碼。監視這個叫openingIndicator的Observable(它發射bufferOpen對象),每當openingIndicator發射了一個數據時,它就創建一個新的List開始收集原始Observable的數據,并將openingIndicator傳遞給closingIndicator函數。這個函數返回一個Observable。buffer監視這個Observable,當它檢測到一個來自這個Observable的數據時,就關閉List并且發射它自己的數據(之前的那個List)。ObservableBufferExactBoundary
不貼方法了,自己看源碼。和ObservableBufferBoundary差不多。
總結
首先需要了解,RxJava被觀察者和觀察者之間的調度流程,個一定要清楚,這樣對分析RxJava的操作符源碼很有幫助,否則你將會陷入代碼無盡的調用中。
Observable的subscribeActual就是做中轉作用,調用到下一個ObservableOnSubscribe的subscribe方法中。