談談對于響應式編程RxJava的理解 - 核心思想篇
談談對于響應式編程RxJava的理解 - 原理篇
源碼分析
我們直接先看一個最簡單的例子
Observable
.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> e) throws Exception {
e.onNext("A");
}
})
// .map(new Function<Object, Object>() {
//
// @Override
// public Object apply(Object o) throws Exception {
// return null;
// }
// })
.subscribe(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Object o) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
map操作符我們現在先不看,先從最簡單的流程開始,Observable不管用create 創建還是just創建其實內部原理是一樣的,我們這里便于分析RxJava的整個流程所以用了create來創建。根據觀察者模式的概念,我們將RxJava的源碼分析過程從簡單到難,拆分為三步進行:
- 1、Observer觀察者的創建
- 2、Observable#create被觀察者的創建
- 3、subscribe訂閱關系的建立
第一步:Observer觀察者的創建
public interface Observer<T> {
/**
* Provides the Observer with the means of cancelling (disposing) the
* connection (channel) with the Observable in both
* synchronous (from within {@link #onNext(Object)}) and asynchronous manner.
* @param d the Disposable instance whose {@link Disposable#dispose()} can
* be called anytime to cancel the connection
* @since 2.0
*/
void onSubscribe(@NonNull Disposable d);
/**
* Provides the Observer with a new item to observe.
* <p>
* The {@link Observable} may call this method 0 or more times.
* <p>
* The {@code Observable} will not call this method again after it calls either {@link #onComplete} or
* {@link #onError}.
*
* @param t
* the item emitted by the Observable
*/
void onNext(@NonNull T t);
/**
* Notifies the Observer that the {@link Observable} has experienced an error condition.
* <p>
* If the {@link Observable} calls this method, it will not thereafter call {@link #onNext} or
* {@link #onComplete}.
*
* @param e
* the exception encountered by the Observable
*/
void onError(@NonNull Throwable e);
/**
* Notifies the Observer that the {@link Observable} has finished sending push-based notifications.
* <p>
* The {@link Observable} will not call this method if it calls {@link #onError}.
*/
void onComplete();
}
Observer其實屬于觀察者模式中的抽象觀察者對象,就是一個接口,里面有onSubscribe開始訂閱回調、onNext拿到事件回調、onError錯誤事件回調、onComplete完成事件回調的抽象方法,我們這里就是new一個這個Observer接口的匿名內部類。
第二步:Observable#create被觀察者的創建
我們先看到Observable.create方法的調用
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
我們點進去RxJavaPlugins.onAssembly看看
@NonNull
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的判空操作,其實RxJava內部并沒有用到,一開始onObservableAssembly初始化后就是空的,
setOnObservableAssembly(null);
按我的理解onObservableAssembly是提供給用戶我們自己用的,我們可以重寫
setOnObservableAssembly。例如:
RxJavaPlugins.setOnObservableAssembly(new Function<Observable, Observable>() {
@Override
public Observable apply(Observable observable) throws Exception {
//例如這里可以加入一下日志打印,可以查看全局哪些地方用到了RxJava
Log.d("RxJava",observable.toString());
return observable;
}
};
如果要重寫setOnObservableAssembly的話,記得return返回observable,這樣才可以繼續RxJava的整個事件流,不然返回null肯定會報錯的。
這里也不是我們分析的重點,我們再看到return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));這句代碼,我們看到這里返回了一個ObservableCreate對象
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
@Override
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);
}
}
ObservableCreate對象是繼承自Observable,的我們先大致看下它的結果,具體先接著看第三步流程,后面再結合起來分析。
第三步:subscribe訂閱關系的建立
直接進入subscribe的源碼
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable has been set or not
// can't call onSubscribe because the call might have set a Subscription already
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
subscribe方法里傳進來的就是我們自定義的observer(就是自己寫的匿名類),前面也是一些初始化和判空操作,我們主要看 subscribeActual(observer);這句代碼。我們點進去發現是Observable里的一個抽象方法
protected abstract void subscribeActual(Observer<? super T> observer);
我們從第二步可以知道ObservableCreate對象是繼承自Observable的,所以這里抽象方法subscribeActual的實現就是在ObservableCreate里,我們看到ObservableCreate里的subscribeActual方法
@Override
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包裝成一個發射器CreateEmitter對象parent,再調用觀察者的observer.onSubscribe(parent);這里實現onSubscribe方法的實際上就是我們自己寫的內部類里的onSubscribe方法,我們看到onSubscribe方法里最終我們調用了發射器CreateEmitter的onNext方法,所以我們進去onNext方法看看
@Override
public void onNext(T t) {
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
我們看到發射器里的onNext方法就是最終調用到我們自定義觀察者observer的
onNext方法。
至此,RxJava最簡單的訂閱關系和收發數據的流程就通了,我們再通過一張簡易的流程圖總結下流程。
那么現在我們再加入map操作符一起分析看看
Map操作符原理分析
我們對上面的代碼進行簡單的修改,并且加入map操作符
注意看代碼注釋
Observable
//ObservableCreate 將自定義source傳進去
.create(
//自定義被觀察者(起點)
new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
}
})
//ObservableCreate.map
.map(new Function<String, Bitmap>() {
@Override
public Bitmap apply(String o) throws Exception {
return null;
}
})
//ObservableMap.subscribe
.subscribe(
//自定義觀察者(終點)
new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Object o) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
其實上面map操作符的作用就是從Observable起點開始,通過map操作符將String類型數據轉化為Bitmap類型數據最后流向終點Observer。
經過之前的分析,我們已經知道Observable. create返回了一個ObservableCreate對象,這時我們如果再調用map操作符的話,就是對ObservableCreate進行了.map的操作了。
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
從源碼可以看出.map操作返回一個ObservableMap,所以上面整個程序的最后一步調用會走到ObservableMap.subscribe。(具體可以看我代碼的注釋)
因為有前面的分析基礎,現在我們直接進入subscribe訂閱流程的代碼
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable has been set or not
// can't call onSubscribe because the call might have set a Subscription already
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
因為我們加入了map操作符,現在這里的subscribeActual(observer);就是調用的
ObservableMap的subscribeActual了,
@Override
public void subscribeActual(Observer<? super U> t) {
source.subscribe(new MapObserver<T, U>(t, function));
}
這里,源碼將自定義觀察者Observer(終點),傳入到MapObserver對象里,將自定義觀察者Observer包裝了一層,new了一個MapObserver對象出來。
而這里的 source.subscribe里的source就是上一層的Observable也就是ObservableCreate,所以這里調用了ObservableCreate的subscribe方法。因為不管是ObservableMap還是ObservableCreate都是繼承自Observable
所以我們再進入Observable的subscribe方法
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable has been set or not
// can't call onSubscribe because the call might have set a Subscription already
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
而這次 subscribeActual(observer);調用的是ObservableCreate的subscribeActual了,而且這次的observer觀察者是自定義觀察者經過包裝之后的MapObserver對象,
@Override
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.onSubscribe(parent);就是調用了我們自定義觀察者(終點的)的onSubscribe, source.subscribe(parent);這句調用的就是自定義被觀察者(起點)的subscribe方法,也就是我們上面流程分析的CreateEmitter發射器的onNext方法,
public void onNext(T t) {
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
而此時的observer.onNext(t);的onNext方法不再是自定義observer的onNext方法了,而是先調用MapObserver的onNext方法
MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
super(actual);
this.mapper = mapper;
}
@Override
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);
}
而這一句代碼 v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");就是真正執行變化的代碼,也就是我們自己重寫的map的apply方法里,最后再調用actual.onNext(v);方法返回整個終點的onNext(v);,到此執行完整個事件流。還是和之前一樣,我再用一張流程圖總結下。