Rxjava基于觀察者模式忽你,一個(gè)完整的觀察者模式要有三個(gè)角色對(duì)象:觀察者幼东,被觀察者,事件科雳。
而且在異步觀察者模式中根蟹,一般會(huì)有三個(gè)相關(guān)的線程:被觀察者線程(事件產(chǎn)生的線程),觀察者線程(處理事件的線程)炸渡,訂閱關(guān)系產(chǎn)生的線程(一般都是主線程)娜亿。
一般情況下,在同步的觀察者模式中(或者我們不進(jìn)行任何線程的切換)蚌堵,事件產(chǎn)生的線程和事件處理線程還有訂閱關(guān)系發(fā)生的線程是同一個(gè)線程(這個(gè)線程就是訂閱關(guān)系產(chǎn)生的線程)买决。
RxJava的觀察者模式是一種擴(kuò)展的觀察者模式,一個(gè)被觀察者可以發(fā)送若干的事件吼畏,這些事件組成了一個(gè)事件隊(duì)列督赤。我們可以針對(duì)每一個(gè)事件或者或者整個(gè)事件隊(duì)列進(jìn)行處理,處理完之后再發(fā)送給觀察者泻蚊。
下面來(lái)介紹一下Rxjava中這三個(gè)角色對(duì)象
-
Observer或者Subscriber躲舌,這是觀察者對(duì)象,用來(lái)處理事件性雄。
Observer處理事件有三個(gè)方法:
onNext()
,onCompleted()
,onError
没卸,onNext()
用來(lái)處理普通事件羹奉,onCompleted()
在事件隊(duì)列已經(jīng)發(fā)送完普通事件的時(shí)候來(lái)調(diào)用,onError()
在事件隊(duì)列發(fā)生錯(cuò)誤的時(shí)候來(lái)調(diào)用onCompleted()
和onError()
是互斥的约计,事件隊(duì)列正常發(fā)送完普通事件的時(shí)候诀拭,應(yīng)該調(diào)用onCompleted()
,出錯(cuò)的時(shí)候應(yīng)該調(diào)用onError()
Subscriber相比于Observer增加了兩個(gè)方法,
onStat()
和unsubscribe()
煤蚌,-
onStart
在訂閱關(guān)系產(chǎn)生耕挨,但是還沒(méi)有發(fā)送事件的時(shí)候調(diào)用,我們可以在這里做一些初始化的工作尉桩。但是要注意筒占,onStart
方法的線程是在訂閱關(guān)系產(chǎn)生的線程,也就是說(shuō)如果訂閱關(guān)系是在主線程產(chǎn)生的蜘犁,onStart
就工作在主線程中翰苫,如果訂閱關(guān)系是在工作線程產(chǎn)生的,那么onStart
就工作在工作線程沽瘦。如果我們對(duì)于初始化的線程有要求革骨,比如要求初始化必須在主線程進(jìn)行,那么我們可以使用
doOnSubscribe()
方法析恋,該方法也是在訂閱關(guān)系產(chǎn)生但是還沒(méi)有發(fā)送事件的時(shí)候調(diào)用,但是該方法可以指定自己要運(yùn)行在哪一個(gè)線程中盛卡。 unsubscribe()
該方法是Subscription
接口的方法助隧,該接口是對(duì) 訂閱關(guān)系 的一個(gè)抽象,代表了一個(gè)訂閱關(guān)系滑沧,Subscriber
實(shí)現(xiàn)了這個(gè)接口并村,并且在subscribe()
方法中返回了這個(gè)接口,借助這個(gè)接口滓技,當(dāng)我們不在需要訂閱被觀察者的時(shí)候哩牍,可以通過(guò)該接口的unsubscribe
方法解除訂閱關(guān)系,從而防止內(nèi)存泄漏令漂。
-
Observable 被觀察者對(duì)象膝昆,用來(lái)產(chǎn)生并發(fā)送事件
-
事件對(duì)象,我們?cè)趧?chuàng)建被觀察者對(duì)象的時(shí)候叠必,要指定被觀察者能夠產(chǎn)生什么樣子的事件荚孵,也就是事件的類(lèi)型
?
接下來(lái)看一下如何產(chǎn)生觀察者對(duì)象和被觀察者對(duì)象
-
觀察者對(duì)象的生成
正常的new方法來(lái)生成觀察者對(duì)象
Subscriber subscriber = new Subscriber(String s){ @Override public void onNext(String s){ } @Override public void onCompleted(){ } @Override public void onError(Throwable e){ } }
?
這就生成了一個(gè)觀察者對(duì)象,該觀察者感興趣的事件類(lèi)型是String
-
被觀察者對(duì)象的生成
Rxjava提了了幾個(gè)不同的方法來(lái)方便我們生成被觀察者對(duì)象
-
Observable.create靜態(tài)方法
Observable observable = Observable.create(new Observable.OnSubscribe(){ @Override public void call(Subscriber subscriber){ subscriber.onNext("hello"); subscriber.onNext("world"); subscriber.onCompleted(); } });
Observable.create方法接受Observable的內(nèi)部類(lèi)Onsubscribe作為參數(shù)纬朝,并把該OnSubscriber存儲(chǔ)起來(lái)收叶,當(dāng)訂閱關(guān)系真正發(fā)生的時(shí)候,通過(guò)OnSubscriber來(lái)調(diào)用觀察者的對(duì)應(yīng)方法共苛,實(shí)現(xiàn)消息的發(fā)送判没。
(Observable為什么不直接存儲(chǔ)Subscriber的引用蜓萄?因?yàn)檫@個(gè)時(shí)候訂閱關(guān)系還沒(méi)有真正發(fā)生,拿不到俺畏濉)
-
Observable.just(T...)
just靜態(tài)方法绕德,通過(guò)傳入一系列的事件對(duì)象T來(lái)生成一個(gè)Observable對(duì)象,當(dāng)訂閱關(guān)系發(fā)生的時(shí)候摊阀,就把一系列的事件對(duì)象發(fā)送到Subscriber的
onNext
方法中 -
Observable.from(Iterator it)
from靜態(tài)方法耻蛇,通過(guò)傳入一個(gè)迭代器,把迭代器中的內(nèi)容作為一系列的事件對(duì)象胞此,從而生成一個(gè)Observable對(duì)象臣咖,當(dāng)訂閱關(guān)系發(fā)生的時(shí)候,把迭代器中的內(nèi)容作為事件發(fā)送給Subscriber的
onNext
方法漱牵。
-
-
訂閱關(guān)系的產(chǎn)生
通過(guò)
observable.subscribe(subscriber)
來(lái)發(fā)生訂閱關(guān)系
那我們看一下在發(fā)生關(guān)系的時(shí)候都做了哪些事情夺蛇,引用 扔物線中的一段代碼
public Subscription subscribe(Subscribe subscribe){
subscribe.onStart();
onSubscribe.call(subscribe);
return subscribe;
}
所以,還記得我們說(shuō)Subscriber實(shí)現(xiàn)了Subscription接口酣胀,以方便在將來(lái)unsubscribe
嗎刁赦?
還記得前面我們說(shuō)Subscriber的onStart
方法在 訂閱關(guān)系 產(chǎn)生的線程中執(zhí)行嗎?
還記得我們Observable的靜態(tài)方法create()需要傳入一個(gè)OnSubscribe對(duì)象作為參數(shù)嗎闻镶?
通過(guò)這段代碼就都清楚了甚脉。
還有什么的要說(shuō)的嗎?
就是我們每次在發(fā)生訂閱關(guān)系的時(shí)候铆农,都需要一個(gè)被觀察者和一個(gè)觀察者牺氨,而觀察者一般都要實(shí)現(xiàn)onNext
,onCompleted
,onError
這三個(gè)方法,我們?cè)陂_(kāi)發(fā)中一般并不是三個(gè)方法都關(guān)心墩剖,比如只關(guān)心onNext
方法猴凹,RxJava給我們提供了subscribe
方法的幾個(gè)重載版本,來(lái)使我們更方便的實(shí)現(xiàn)訂閱岭皂。
比如
observable.subscribe(new Action1<String>(){
@Override
public void call(String s){
}
});
先說(shuō)一下ActionX<T>接口郊霎,這個(gè)接口有一個(gè)方法call(),X為N爷绘,則call方法就有N個(gè)參數(shù)书劝,并且ActionX的call方法是沒(méi)有返回值的。
比如Action1<String>就說(shuō)明call
方法有一個(gè)參數(shù)揉阎,該參數(shù)的類(lèi)型是String庄撮。而onNext
方法也是無(wú)返回值,也是只有一個(gè)參數(shù)毙籽,所以在上面的代碼中洞斯,RxJava就會(huì)幫助我們生成一個(gè)Subscriber,并且在這個(gè)為我們生成的Subscriber的onNext
方法中,調(diào)用這個(gè)Action1的call
方法烙如。類(lèi)似于Python中的閉包么抗。