將從Rx一個最簡單的流程說起,說到map,說到SubscribeOn,說到observeOn,說到天荒地老
一個完整流程
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Object> e) throws Exception {
System.out.println("工作空間");
}
}).subscribe(new Observer<Object>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
System.out.println("已連線觀察通道");
}
@Override
public void onNext(@NonNull Object o) {
System.out.println("接受工作空間傳送的事件");
}
@Override
public void onError(@NonNull Throwable e) {
System.out.println("出錯");
}
@Override
public void onComplete() {
System.out.println("完成");
}
});
複製程式碼
接下來看圖分析整個流程做了什麼
文字描述:被觀察者呼叫subscribe
(訂閱)觀察者,然後被觀察者通過呼叫ObservableEmitter
(發射器)發射各種事件(onNext
、onError
、onComplete
)
轉換事件
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
System.out.println("工作空間。我傳送的是string型別資料");
}
}).map(new Function<String, Integer>() {
@Override
public Integer apply(@NonNull String o) throws Exception {
System.out.println("將string轉換成int返回");
return o.length();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
System.out.println("已連線觀察通道");
}
@Override
public void onNext(@NonNull Integer o) {
System.out.println("接受工作空間傳送的事件,接受到的是int型別");
}
@Override
public void onError(@NonNull Throwable e) {
System.out.println("出錯");
}
@Override
public void onComplete() {
System.out.println("完成");
}
});
複製程式碼
可以看到,一開始的被觀察者發射的型別是String
,而觀察者接受的型別是Integer
型別。我要的是寶馬你卻給我電單車?WTF?
這個時候就需要用到map
這個操作符了,可以相當於一箇中轉站(加工站),將被觀察者傳送過來的資料轉換成符合觀察者需要的資料,然後再將它返回給觀察者。完美!
But,how it work??
接下來看圖分析整個流程做了什麼
注:上述圖傳遞的不是ObservableEmitter
,而是為了更直觀瞭解流程,而實際具體流程也差不多,只是實現不太一樣。
文字描述:
①:原始被觀察者
呼叫map()
的時候,重新建立了一個被觀察者(這裡稱它為Map被觀察者
),然後用Map被觀察者
訂閱原始觀察者
。
②:然後在訂閱成功後,原始被觀察者
將訂閱一個新的觀察者(這裡稱它為Map觀察者
)。
③:然後原始被觀察者
在傳送(String)訊息的時候,Map觀察者
接受到(String)訊息,將(String)訊息通過apply()
方法將其轉為(Integer)訊息,並通過Map被觀察者
傳送給原始觀察者
。
④:apply()
方法是我們自己實現的方法
Map簡單程式碼如下
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
return create(new ObservableOnSubscribe<R>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> e) {
subscribe(new Observer<T>() {
@Override
public void onNext(T var1) {
e.onNext(mapper.call(var1));
}
});
}
});
}
複製程式碼
轉換執行緒(SubscribeOn)
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
System.out.println("工作空間。我傳送的是string型別資料");
}
}).subscribeOn(Schedulers.io())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
System.out.println("已連線觀察通道");
}
@Override
public void onNext(@NonNull String o) {
System.out.println("接受工作空間傳送的事件,接受到的是int型別");
}
@Override
public void onError(@NonNull Throwable e) {
System.out.println("出錯");
}
@Override
public void onComplete() {
System.out.println("完成");
}
});
複製程式碼
接下來看圖分析整個流程做了什麼
文字分析:和map類似的操作,但又有點不同
①:原始被觀察者
呼叫subscribeOn()
的時候,重新建立了一個被觀察者(這裡稱它為subscribeOn被觀察者
),然後用subscribeOn被觀察者
訂閱原始觀察者
。
②:然後在訂閱成功後,進行執行緒的轉換
。
③:在subscribeOn被觀察者
中呼叫原始被觀察者
的subscribe(ObservableEmitter<Object> e)
,其中的引數發射器e
用的是subscribeOn被觀察者
的發射器
subscribeOn()簡單程式碼如下
public final Observable<T> subscribeOn(Scheduler scheduler){
return Observable.create(new ObservableOnSubscribe<T>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
// 執行緒的轉換
scheduler.createWorker().schedule(new SubscribeTask() {
@Override
public void run() {
// source為原始被觀察者
source.call(e);
}
});
}
});
}
複製程式碼
轉換執行緒(observeOn)
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
System.out.println("工作空間。我傳送的是string型別資料");
}
}).observeOn(Schedulers.io())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
System.out.println("已連線觀察通道");
}
@Override
public void onNext(@NonNull String o) {
System.out.println("接受工作空間傳送的事件,接受到的是int型別");
}
@Override
public void onError(@NonNull Throwable e) {
System.out.println("出錯");
}
@Override
public void onComplete() {
System.out.println("完成");
}
});
複製程式碼
接下來看圖分析整個流程做了什麼
文字分析:和map比較類似的操作,但又有點不同
①:原始被觀察者
呼叫observeOn()
的時候,重新建立了一個被觀察者(這裡稱它為observeOn被觀察者
),然後用observeOn被觀察者
訂閱原始觀察者
。
②:然後訂閱成功後將建立一個觀察者(這裡稱為observeOn觀察者
),作為引數呼叫原始被觀察者
的subscribe(@NonNull ObservableEmitter<Object> e)
。
③:之後的原始被觀察者
傳送的onNext
事件都會先經過observeOn觀察者
的onNext
事件先,在裡面會進行執行緒的轉換
,再呼叫observeOn被觀察者
的發射器來
傳送onNext
事件給原始觀察者
。
observeOn()簡單程式碼如下
public final Observable<T> observeOn(Scheduler scheduler) {
return Observable.create(new ObservableOnSubscribe<T>() {
@Override
public void subscribe(@NonNull Observer<Object> e) {
// source為原始被觀察者
source.subscribe(new Observer<T>() {
@Override
public void onNext(T var1) {
// 執行緒的轉換
scheduler.createWorker().schedule(new Runnable() {
@Override
public void run() {
// e為observeOn被觀察者
e.onNext(var1);
}
});
}
});
}
});
}
複製程式碼
結語
其實RxJava裡面的各種操作符大部分都是利用了這種思想,用各種Observable和Observer來達到目的。 observeOn和subscribeOn對執行緒的排程94這樣,對於裡面什麼方法走在什麼執行緒,應該理解上面所說的就應該清楚了。