RxJava 原始碼分析系列(四) -操作符變換原理
我們繼續來學習RxJava的原始碼,今天主要會學習RxJava中的操作符變換原理。
本文重點講解Observable
,Flowable
跟Observable
非常的像,所以就不做講解。
1.概述
就Observable而言,操作符變化主要涉及的兩個類:AbstractObservableWithUpstream
和ObservableOperator
。
其中,我們可以看到的是,RxJava給我們的變換操作符,包括map
,flatMap
、buffer
等操作符等繼承於AbstractObservableWithUpstream
類。
而ObservableOperator
介面主要用於自定義操作符,然後配合lift
操作符,美滋滋??。
AbstractObservableWithUpstream
和ObservableOperator
都有一個共同的特點,那就是進行變換時,都會找一箇中間的Observer
。Observable
先將資料傳遞到中間的Observer
的onNext
方法,然後在onNext
方法進行變換,變換之後,在傳遞給我們的Observer
。這一點,我們必須瞭解。
2. AbstractObservableWithUpstream
我們先來看看AbstractObservableWithUpstream
這個類,看一下這個類為我們做了哪些事情。
abstract class AbstractObservableWithUpstream<T, U> extends Observable<U> implements HasUpstreamObservableSource<T> {
protected final ObservableSource<T> source;
AbstractObservableWithUpstream(ObservableSource<T> source) {
this.source = source;
}
@Override
public final ObservableSource<T> source() {
return source;
}
}
首先,我們看到的是,AbstractObservableWithUpstream
是包許可權,也就是RX官方也不希望我們來使用這個類。
這個類表示的意思非常簡單,實現了HasUpstreamObservableSource
介面,並且實現了source
方法,返回了一個ObservableSource
物件。
我們感覺AbstractObservableWithUpstream
根本沒做什麼事情,是的,我也這麼覺得??。
為了更好理解操作變換原理,我們來簡單的看看map
操作符。關於操作符的理解,本文只是簡單做一個理解,如果後續有需要的話,可以對某些操作符做單獨的分析。
(1).map操作符
map
操作符主要涉及到的是ObservableMap
類,主要是在這個類對中間Observer
進行了subscribe
。我們來看看:
public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends U> function;
public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
super(source);
this.function = function;
}
@Override
public void subscribeActual(Observer<? super U> t) {
source.subscribe(new MapObserver<T, U>(t, function));
}
}
我們看到,在subscribeActual
方法裡面進行了subscribe
操作,然後Observable
的onNext
等操作都會執行到MapObserver
相應的操作當中來。
我們知道,map
操作主要是將一個資料從一種型別轉換為另一個種型別。而這種實現主要是在onNext方法裡面進行的,我們來看看MapObserver
的onNext
方法:
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
actual.onNext(null);
return;
}
U v;
try {
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
actual.onNext(v);
}
在onNext
方法裡面,呼叫了Function
的apply
方法將一個資料從一個型別轉換為另一個型別,然後在呼叫我們的Observer
的onNext
方法將轉換之後的資料傳遞下去。這就是整個map
轉換的過程。
從這裡,可以應證前面的一點,那就是需要一箇中間Observer
來實現。這種實現方法相當於是一個組合式的代理模式,代理物件是中間的Observer
,真正做操作的是我們的Observer
。
3. ObservableOperator
我們來看看ObservableOperator
類,看看我們怎麼通過ObservableOperator
來自定義一個操作符。之前說過,ObservableOperator
需要跟lift
操作符來實現。所以,我們先來看看lift
操作符:
public final <R> Observable<R> lift(ObservableOperator<? extends R, ? super T> lifter) {
ObjectHelper.requireNonNull(lifter, "onLift is null");
return RxJavaPlugins.onAssembly(new ObservableLift<R, T>(this, lifter));
}
好吧,我們來看看ObservableLift
:
public final class ObservableLift<R, T> extends AbstractObservableWithUpstream<T, R> {
final ObservableOperator<? extends R, ? super T> operator;
public ObservableLift(ObservableSource<T> source, ObservableOperator<? extends R, ? super T> operator) {
super(source);
this.operator = operator;
}
@Override
public void subscribeActual(Observer<? super R> s) {
Observer<? super T> observer;
try {
observer = ObjectHelper.requireNonNull(operator.apply(s), "Operator " + operator + " returned a null Observer");
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
source.subscribe(observer);
}
}
在這個類裡面,主要是在subscribeActual
方法裡面做了一次apply
的操作,通過這個操作,我們獲取了一個新的Observer
,這個新的Observer
就是我們的Observer
,然後再subscribe
。這個也是非常的簡單。現在我們來通過一個小小的案例來實現一個map
操作符。
(1).實現Map操作符
我們先定義了一個ObserverMap
用來將一個U型別轉換為T型別
public class ObserverMap<T, U> implements ObservableOperator<T, U> {
private Function<U, T> mFunction;
public ObserverMap(Function<U, T> function) {
this.mFunction = function;
}
@Override
public Observer<? super U> apply(final Observer<? super T> observer) throws Exception {
return new Observer<U>() {
@Override
public void onSubscribe(Disposable d) {
observer.onSubscribe(d);
}
@Override
public void onNext(U u) {
observer.onNext(mFunction.apply(u));
}
@Override
public void onError(Throwable e) {
observer.onError(e);
}
@Override
public void onComplete() {
observer.onComplete();
}
};
}
}
整個類也是非常的簡單,只在onNext
方法中做了一次型別轉換。
然後,我們看一下,是怎麼使用的:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
}
}).lift(new ObserverMap<>(new Function<Integer, String>() {
@Override
public String apply(Integer input) {
return "input = " + String.valueOf(input);
}
})).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i("pby123", s);
}
});
4.總結
總的來說,這篇文章是非常的簡單的,這裡的講解主要對後面打一個基礎,後續有可能會對一些操作符進行分析,同時講解一下這個,相信大家以後看到相關的程式碼不會懵逼。
相關文章
- Rxjava 2.x 原始碼系列 - 變換操作符 Map(上)RxJava原始碼
- RxJava2原始碼分析(二):操作符原理分析RxJava原始碼
- RxJava操作符系列四RxJava
- RxJava操作符之轉換操作符(四)RxJava
- 解剖 RxJava 之變換操作符RxJava
- RxJava2.0——變換操作符RxJava
- RxJava 學習筆記 -- 變換操作符RxJava筆記
- RxJava2.x 分析原始碼,理解操作符FlatMapRxJava原始碼
- RxJava2.x 從原始碼分析原理RxJava原始碼
- RxJava 操作符系列二RxJava
- RxJava操作符系列一RxJava
- RxJava操作符系列二RxJava
- RxJava操作符系列三RxJava
- RxJava 操作符系列五RxJava
- RxJava小考題 -- Rxjava原始碼分析(一)RxJava原始碼
- Rxjava 2.x 原始碼系列 - 基礎框架分析RxJava原始碼框架
- Android RxJava使用介紹(四) RxJava的操作符AndroidRxJava
- Vue原始碼分析系列四:Virtual DOMVue原始碼
- Rxjava 2.x 原始碼系列 - 執行緒切換 (下)RxJava原始碼執行緒
- Rxjava 2.x 原始碼系列 - 執行緒切換 (上)RxJava原始碼執行緒
- 10章 RxJava原始碼分析RxJava原始碼
- RxJava2原始碼分析RxJava原始碼
- 讀RxJava原始碼:理解subscribe原理RxJava原始碼
- RxJava操作符系列六 | 掘金技術徵文RxJava
- RxJava2原始碼分析(一):基本流程分析RxJava原始碼
- 友好 RxJava2.x 原始碼解析(三)zip 原始碼分析RxJava原始碼
- 四. RxJava之基本原理RxJava
- 【JDK原始碼分析系列】ArrayBlockingQueue原始碼分析JDK原始碼BloC
- RxJava常用操作符RxJava
- RxJava操作符列表RxJava
- preact原始碼分析(四)React原始碼
- 容器類原始碼解析系列(四)---SparseArray分析(最新版)原始碼
- GCD原始碼原理分析GC原始碼
- Spark 原始碼分析系列Spark原始碼
- RxJava2.0(四)執行緒之間切換的內部原理RxJava執行緒
- RxJava2.0 操作符(3)—— Filter 過濾轉換符RxJavaFilter
- RxJava原始碼初探RxJava原始碼
- RxJava操作符之建立操作符(三)RxJava