本篇文章已受權微信公衆號 YYGeeker
獨家發佈轉載請標明出處java
CSDN學院課程地址bash
- RxJava2從入門到精通-初級篇:edu.csdn.net/course/deta…
- RxJava2從入門到精通-中級篇:edu.csdn.net/course/deta…
- RxJava2從入門到精通-進階篇:edu.csdn.net/course/deta…
- RxJava2從入門到精通-源碼分析篇:edu.csdn.net/course/deta…
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);
}
}
複製代碼
PublishSubject不會改變事件的發送順序。若是在已經發送了一部分事件以後註冊的observer,是不會收到以前發送的事件async
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();
}
複製代碼
輸出結果ide
first onNext=1
first onNext=2
first onNext=3
seconde onNext=3
first onComplete
seconde onComplete
複製代碼
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();
}
複製代碼
輸出結果this
first onNext=默認值
first onNext=1
first onNext=2
seconde onNext=2
first onNext=3
seconde onNext=3
first onComplete
seconde onComplete
複製代碼
ReplaySubject不管何時註冊observer,不管什麼時候經過ReplaySubject發射的全部事件,均會發送給新的observerspa
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();
}
複製代碼
輸出結果.net
first onNext=1
first onNext=2
seconde onNext=1
seconde onNext=2
first onNext=3
seconde onNext=3
first onComplete
seconde onComplete
複製代碼
只有當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
複製代碼
每種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
複製代碼