既然是進階知識,假定你已經擁有RxJava相關的使用經驗,所以我就不多逼逼它的好了,本文將結合原始碼,來分析一個Observable是如何發出事件的。
Context
- rxjava:1.0.16
- 本文貼出的rxjava原始碼都是精簡過的,旨在簡潔地表達原始碼意圖
1. 概念準備,何為上/下游事件?
上/下游事件,是在Rx中用來描述事件所處位置的,這其實是一個相對的概念。我使用一段示例程式碼來解釋這個概念。
Observable
.just("hello")
.map(s->s+=‘OK’)
.subscribe(Action1->{...})
複製程式碼
按照我們上面程式碼來分析,just
在map
的上面,而Action1
在map
的下面,資料傳遞流程是這樣的:just->map->Action1
,所以對於map
來說,just
是它的上游,而Action1
是它的下游。在Rx中,事件是從上游流向下游的。
2. 上游事件是如何產生的?
我將選擇一個較簡單的Create Operator--just
來作為例子。
Observable
.just("hello")
.subscribe(Action1->{...})
複製程式碼
2.1 精簡過後的just(T t)
原始碼
public static <T> Observable<T> just(final T value) {
return ScalarSynchronousObservable.create(value);
}
....
// 現階段先不管Scalar到底是個啥,我們知道
// SynchronousObservable是一個同步的Observable就夠了
-- ScalarSynchronousObservable.java
public static <T> ScalarSynchronousObservable<T> create(T t) {
return new ScalarSynchronousObservable<T>(t);
}
protected ScalarSynchronousObservable(final T t) {
super(new JustOnSubscribe<T>(t));
this.t = t;
}
-- Observable.java
public class Observable<T> {
final OnSubscribe<T> onSubscribe;
protected Observable(OnSubscribe<T> f) {
this.onSubscribe = f;
}
.....
}
複製程式碼
結論1: just()
呼叫完之後,返回的是一個新的Observable
,而這個Observable
的onSubcribe
也是新的,他叫JustOnSubscribe
,然而這個t
,就是我們傳進來的"hello"。
目前為止,我們已經有一個Observable,和兩個onSubcriber了,一個是ScalarSynchronousObservable生成的,一個是我們傳入subscribe()中的。
在剛剛的分析中,我們並沒有看到觸發Subscriber的邏輯,我們剛剛猜想,是subscribe方法促使“Hello”傳遞到Action1的,那麼我們來看看Observable.subscribe方法的具體實現。
2.2 Observable.subscribe()
---Observable.java
public final Subscription subscribe(final Action1<? super T> onNext) {
Action1<Throwable> onError = InternalObservableUtils.ERROR_NOT_IMPLEMENTED;
Action0 onCompleted = Actions.empty();
// 如果在subscribe中傳遞的是Action,而不是subscriber
// 那麼Observable內部會將Action組裝成一個Subscriber(其實Subscriber內部也是由Action通過組合的方式實現的,有點像代理模式)
return subscribe(new ActionSubscriber<T>(onNext,onError,onCompleted));
}
public final Subscription subscribe(Subscriber<? super T> subscriber) {
// 因為just()操作符會生成一個新的Observable
// 所以我們在鏈式呼叫中執行的subscribe方法
// 也就是新Observable的方法
// 要記得新Observable.onSubcribe物件也是新的,它叫JustOnSubscribe
return Observable.subscribe(subscriber, this);
}
static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
subscriber.onStart();
try {
//這麼一來,justOnSubscribe.call()裡到底執行了什麼就很關鍵了
justOnSubscribe.call(subscriber)
//原始碼:RxJavaHooks.onObservableStart(observable,observable.onSubscribe).call(subscriber);
// Subscriber是Observer的同時也是Subscription
// 直接返回以便進行unsubscribed()操作
return subscriber;
//原始碼:RxJavaHooks.onObservableReturn(subscriber)
} catch (Throwable e) {
// throw exceptions
}
return Subscriptions.unsubscribed();
}
}
--- ScalarSynchronousObservable.java
static final class JustOnSubscribe<T> implements OnSubscribe<T> {
final T value;
JustOnSubscribe(T value) {
this.value = value;
}
@Override
public void call(Subscriber<? super T> s) {
s.setProducer(createProducer(s, value));
}
}
static <T> Producer createProducer(Subscriber<? super T> s, T v){
// 這個常量我們先不管,它預設為false
if (STRONG_MODE) {
return new SingleProducer<T>(s, v);
}
//我們預設認為返回WeakSingleProducer即可
return new WeakSingleProducer<T>(s, v);
}
複製程式碼
我在上面程式碼寫了一些註釋,對一些較為關鍵的點做了分析。
現在我們再來昇華一下,做一個Observable.subscribe()
呼叫流程的最後結論:
- 在
Observable.subscribe()
方法中,呼叫了OnSubscribe.call()
- 因為在
just()
中,生成了一個新的Observable
物件,並且Observable.onSubscribe
為JustOnSubscribe
justOnSubscribe.call(subscriber)
的subscriber
,是RxJava根據我們在subscribe()
傳遞的Action1
生成的ActionSubscriber。justOnSubscribe.call()
中,生成了一個WeakSingleProducer
,並且為ActionSubscriber
設定了WeakSingleProducer
。
接下來,我們要把目光轉移到,Subscriber.setProducer()
和WeakSingleProducer
這個類上了.
2.3 subscriber.setProducer
--- Subscriber.java
public void setProducer(Producer p) {
// 對於本例,省略一些背壓和併發控制的邏輯程式碼
// 以下為精簡後的原始碼
producer.request(Long.MAX_VALUE);
}
複製程式碼
2.4 weakSingleProducer.request
static final class WeakSingleProducer<T> implements Producer {
final Subscriber<? super T> actual;
final T value;
boolean once;
public WeakSingleProducer(Subscriber<? super T> actual, T value) {
this.actual = actual;
this.value = value;
}
@Override
public void request(long n) {
if (once) {
return;
}
if (n < 0L) {
throw new IllegalStateException("n >= required but it was " + n);
}
if (n == 0L) {
return;
}
once = true;
Subscriber<? super T> a = actual;
if (a.isUnsubscribed()) {
return;
}
T v = value;
try {
a.onNext(v);
} catch (Throwable e) {
Exceptions.throwOrReport(e, a, v);
return;
}
if (a.isUnsubscribed()) {
return;
}
a.onCompleted();
}
}
複製程式碼
我們可以在WeakSingleProducer.request
中很清晰的看到Subscriber
的回撥方法的執行。我們的“Hello”字串也是在這裡傳遞到下游的Action1
中的。
所以,我們是時候開始總結一波了!
2.5 完整的Observable事件產生流程
示例程式碼回顧:
Observable
.just("hello")
.map(s->s+=‘OK’)
.subscribe(Action1->{...})
複製程式碼
-
所以,對以上簡單的Rx程式碼,是如何產生事件的分析結論是:
just()
函式會建立一個新的Observable
,並且這個Observable.OnSubscribe
會被設定一個JustOnSubscribe
- 在
Observable.subcribe()
方法中,呼叫了JustOnSubscribe.call()
- 在
JustOnSubscribe.call()
中,生成Producer
用於處理下游最終資料的分發
-
具體流程圖如下:
2.6 廢話
其實,通過這次的分析得到的結論,我們可以做很多的猜想:
- map,flatMap這樣的變換操作符的變換(Lift)流程是咋樣的呢?是否也是通過包裝Observable來達到的呢?
- Schedular的排程流程是咋樣的呢?是否也是通過包裝Observable來達到的呢?
不久的將來,我也會通過原始碼來冷靜分析一波