本篇文章已授權微信公眾號 YYGeeker
獨家釋出轉載請標明出處
CSDN學院課程地址
- RxJava2從入門到精通-初級篇:edu.csdn.net/course/deta…
- RxJava2從入門到精通-中級篇:edu.csdn.net/course/deta…
- RxJava2從入門到精通-進階篇:edu.csdn.net/course/deta…
- RxJava2從入門到精通-原始碼分析篇:edu.csdn.net/course/deta…
8. RxJava高階用法(二)
8.1 Subject的介紹
Subject可以看成是一個橋樑或者代理,在RxJava中同時充當了Observer和Observable的角色,即事件流的傳送方和接收方。因為它是一個Observer,它可以訂閱一個或多個Observable;又因為它是一個Observable,它可以轉發它收到(Observe)的資料,也可以發射新的資料。為了方便演示,在開始講解Subject之前,我們統一建立出SubjectObserver
static class SubjectObserver<T extends String> implements Observer<String> {
String name;
public SubjectObserver(String name) {
this.name = name;
}
@Override
public void onError(Throwable e) {
System.out.println("onError " + e.getStackTrace());
}
@Override
public void onComplete() {
System.out.println(name + " onComplete");
}
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(java.lang.String s) {
System.out.println(name + " onNext=" + s);
}
}
複製程式碼
8.2 PublishSubject
PublishSubject不會改變事件的傳送順序。如果在已經傳送了一部分事件之後註冊的observer,是不會收到之前傳送的事件
public static void publishSubject() {
PublishSubject publishSubject = PublishSubject.create();
publishSubject.subscribe(new SubjectObserver<>("first"));
publishSubject.onNext("1");
publishSubject.onNext("2");
publishSubject.subscribe(new SubjectObserver<>("seconde"));
publishSubject.onNext("3");
publishSubject.onComplete();
}
複製程式碼
輸出結果
first onNext=1
first onNext=2
first onNext=3
seconde onNext=3
first onComplete
seconde onComplete
複製程式碼
8.3 BehaviorSubject
BehaviorSubject會建立出帶有預設值的事件流。當BehaviorSubject第一次被observer註冊時,如果observable中沒有發射資料項的時候,就會將預設值發給observer;如果observable中有發射過資料項的時候,就會將最近發射的資料項發給observer
public static void behaviorSubject(View view) {
BehaviorSubject<String> behaviorSubject = BehaviorSubject.createDefault("預設值");
behaviorSubject.subscribe(new SubjectObserver<String>("first"));
behaviorSubject.onNext("1");
behaviorSubject.onNext("2");
behaviorSubject.subscribe(new SubjectObserver<String>("seconde"));
behaviorSubject.onNext("3");
behaviorSubject.onComplete();
}
複製程式碼
輸出結果
first onNext=預設值
first onNext=1
first onNext=2
seconde onNext=2
first onNext=3
seconde onNext=3
first onComplete
seconde onComplete
複製程式碼
8.4 ReplaySubject
ReplaySubject無論什麼時候註冊observer,無論何時通過ReplaySubject發射的所有事件,均會傳送給新的observer
public static void replaySubject(View view) {
ReplaySubject<String> replaySubject = ReplaySubject.create();
replaySubject.subscribe(new SubjectObserver<>("first"));
replaySubject.onNext("1");
replaySubject.onNext("2");
replaySubject.subscribe(new SubjectObserver<>("seconde"));
replaySubject.onNext("3");
replaySubject.onComplete();
}
複製程式碼
輸出結果
first onNext=1
first onNext=2
seconde onNext=1
seconde onNext=2
first onNext=3
seconde onNext=3
first onComplete
seconde onComplete
複製程式碼
8.5 AsyncSubject
只有當AsyncSubject呼叫onComplete方法時,才會將AsyncSubject中的最後一個事件傳遞給observer。如果不呼叫onComplete方法,則不會給observer傳送任何事件
public static void asyncSubject(View view) {
AsyncSubject asyncSubject = AsyncSubject.create();
asyncSubject.subscribe(new SubjectObserver<String>("first"));
asyncSubject.onNext("1");
asyncSubject.onNext("2");
asyncSubject.onNext("3");
asyncSubject.onComplete();
asyncSubject.subscribe(new SubjectObserver<String>("seconde"));
asyncSubject.onComplete();
}
複製程式碼
輸出結果
first onNext=3
first onComplete
seconde onNext=3
seconde onComplete
複製程式碼
8.6 轉發資料
每種Subject都可以當作是轉發資料的橋樑,在轉發資料的過程中,具體使用哪種應該參考對應的應用場景,通常在元件之間的通訊就需要用到Subject。比如下面這個例子,從元件A中將資訊傳遞給元件B,元件B會收到元件A傳送過來的訊息,如果需要元件B將資訊傳遞給元件B,則需要將程式碼的觀察者角色和被觀察者角色調換過來。通常情況下,元件A和元件B都會同時依附於同一個Activity或Fragment,在Activity或Fragment中應該提供獲取Subject的方法,讓元件雙方可以獲取橋樑,從而互相subscribe,最終形成通訊
public static void transpondData(View view){
//元件A
Observable<String> observable = Observable.fromArray("123","456","789");
ReplaySubject<String> replaySubject = ReplaySubject.create();
observable.subscribe(replaySubject);
replaySubject.subscribe(new SubjectObserver<>("B"));//元件B
}
複製程式碼
輸出結果
B onNext=123
B onNext=456
B onNext=789
B onComplete
複製程式碼
8.7 小結
- PublishSubject:從註冊時開始接收新的資料項
- BehaviorSubject:從註冊時會收到以前最近的一條資料項,如果沒有則收到預設值
- ReplaySubject:無論何時註冊,都會收到以前傳送過的所有資料項到新的observer
- AsyncSubject:只有呼叫onComplete時,才會收到最後一個資料項
- 轉發資料:A可以轉發給B,B可以轉發給A,主要是看誰subscribe誰