subject是個神奇的對象襟锐,他可以是一個Observable(觀察)同時也可以是一個Observer(觀察者):它作為鏈接這兩個世界的橋梁挺身。一個Subject可以訂閱一個Observable艳狐,就像一個觀察者蹭劈,并且它可以發(fā)射新的數(shù)據(jù)厌处,就像一個Observable侦另。很明顯特纤,作為Obserable军俊,觀察者們或者其它Subject都可以訂閱它。
一旦Subhect訂閱了Observable捧存,他將會觸發(fā)Observable開始發(fā)射粪躬。如果原始的Observable是“冷”的担败,這將會對訂閱一個“熱”的Observable變量產(chǎn)生影響。
RxJava提供了四種不同的Subject:
- PublishSubject (發(fā)布)
- BehaviorSubject (行為/反應(yīng))
- ReplaySubject (重播)
- AsyncSubject (異步)
PublishSubject
Publish是Subject的一個基礎(chǔ)子類镰官。讓我們看看用PublishSubject實現(xiàn)傳統(tǒng)的Observable
PublishSubject<String> stringPublishSubject = PublishSubject.create();
Subscription subscriptionPrint = stringPublishSubject.subscribe(new Observer<String>() {
@Override
public void onCompleted() {
System.out.println("Observable completed");
}
@Override
public void onError(Throwable e) {
System.out.println("Oh,no!Something wrong happened!");
}
@Override
public void onNext(String message) {
System.out.println(message);
}
});
stringPublishSubject.onNext("Hello World");
在剛才的例子中提前,我們創(chuàng)建一個PulishSubject,用create()發(fā)射一個S聽值朋魔,然后我們訂閱PublishSubject岖研。此時,沒有數(shù)據(jù)要發(fā)送警检,因此我們的觀察者只能等待孙援,沒有阻塞線程,也沒有資源消耗扇雕。
最后一行代碼展示了手動發(fā)射字符串“Hello World”,它觸發(fā)了觀察者的onNext()方法拓售,讓我們在控制臺打印出“Hello World”信息。
讓我們看一個更復(fù)雜的例子镶奉。話說我們有一個private聲明的Observable础淤,外部不能訪問。Observable在它生命周期內(nèi)發(fā)射值哨苛,我們不用關(guān)心這些值鸽凶,我們只關(guān)心他們的結(jié)束。
首先建峭,我們創(chuàng)建一個新的PublishSubject來響應(yīng)它的onNext()方法玻侥,并且外部也可以訪問它。
final PublishSubject<Boolean> subject = PublishSubject.create();
subject.subscribe(new Observer<Boolean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Boolean aBoolean) {
System.out.println("Observable Completed");
}
});
然后亿蒸,我們創(chuàng)建“私有”的Observable凑兰,只有subject才可以訪問的到。
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
for (int i = 0; i < 5; i++) {
subscriber.onNext(i);
}
subscriber.onCompleted();
}
}).doOnCompleted(new Action0() {
@Override
public void call() {
subject.onNext(true);
}
}).subscribe();
observable.create()方阿飛包含了我們for循環(huán)边锁,發(fā)射數(shù)字姑食。doOnCompleted()方法指定當(dāng)Observable結(jié)束時要做什么事情;在subject上發(fā)射true茅坛。最后音半,我們訂閱了Observable。很明顯贡蓖,空的subscribe()調(diào)用僅僅是為了開啟Observable祟剔,而不用管已發(fā)出的任何值,也不用管完成事件或者錯誤事件摩梧。為了這個例子我們需要它像這樣物延。
在這個例子中,我們創(chuàng)建了一個可以連接Observables并且同時可被觀測的實體仅父。當(dāng)我們想為公共資源創(chuàng)建獨立叛薯、抽象或更易觀測的點時浑吟,這是極其有用的。
BehaviorSubject
簡單的說耗溜,BehaviorDSubject會首先向他的訂閱這發(fā)送截至訂閱前最新的一個數(shù)據(jù)對象(或初始值)组力,然后正常發(fā)送訂閱后的數(shù)據(jù)流。
BehaviorSubject<Integer> behaviorSubject = BehaviorSubject.create(1);