一.原理學(xué)習(xí)
核心:觀察者模式
觀察者模式:A 對象(觀察者)對 B 對象(被觀察者)的某種變化高度敏感捺疼,需要在 B 變化的一瞬間做出反應(yīng)婚被。
注意:觀察者不需要時刻盯著被觀察者(例如 A 不需要每過 2ms 就檢查一次 B 的狀態(tài))公你,而是采用注冊(Register)或者稱為訂閱(Subscribe)的方式慌植,告訴被觀察者:我需要你的某某狀態(tài)休雌,你要在它變化的時候通知我灶壶。
舉例說明:Android開發(fā)中一個比較典型的例子是點擊監(jiān)聽器OnClickListener。對設(shè)置OnClickListener來說挑辆,View是被觀察者例朱,OnClickListener是觀察者,二者通過setOnClickListener()方法達成訂閱關(guān)系鱼蝉。訂閱之后用戶點擊按鈕的瞬間洒嗤,Android Framework 就會將點擊事件發(fā)送給已經(jīng)注冊的?OnClickListener?。采取這樣被動的觀察方式魁亦,既省去了反復(fù)檢索狀態(tài)的資源消耗渔隶,也能夠得到最高的反饋速度。
簡單理解就是:A(觀察者) ==》B(被觀察者)? 注冊訂閱關(guān)系
當(dāng)B發(fā)生變化的時候會通知A洁奈,A做出相應(yīng)的操作间唉。
針對監(jiān)聽器OnClickListener的例子展開說明:
如圖所示,通過setOnClickListener()方法利术,Button持有OnClickListener的引用呈野;當(dāng)用戶點擊時,Button自動調(diào)用OnClickListener的onClick()方法印叁。另外被冒,如果把這張圖中的概念抽象出來(Button?->被觀察者军掂、OnClickListener?->觀察者、setOnClickListener()?->訂閱昨悼,onClick()?->事件)
變成下面通用的觀察者模式
RxJava的觀察者模式
RxJava有四個基本概念:Observable?(可觀察者蝗锥,即被觀察者)、Observer?(觀察者)率触、subscribe?(訂閱)终议、事件。Observable和Observer通過subscribe()方法實現(xiàn)訂閱關(guān)系葱蝗,從而Observable可以在需要的時候發(fā)出事件來通知Observer穴张。
RxJava的事件回調(diào)方法除了普通事件onNext()(相當(dāng)于onClick()?/?onEvent())之外,還定義了兩個特殊的事件:onCompleted()和onError()垒玲。
onCompleted():事件隊列完結(jié)陆馁。RxJava不僅把每個事件單獨處理,還會把它們看做一個隊列合愈。RxJava規(guī)定叮贩,當(dāng)不會再有新的onNext()發(fā)出時,需要觸發(fā)onCompleted()方法作為標(biāo)志佛析。
onError(): 事件隊列異常益老。在事件處理過程中出異常時,onError()?會被觸發(fā)寸莫,同時隊列自動終止捺萌,不允許再有事件發(fā)出。
在一個正確運行的事件序列中,?onCompleted()?和?onError()?有且只有一個膘茎,并且是事件序列中的最后一個桃纯。需要注意的是,onCompleted()?和?onError()?二者也是互斥的披坏,即在隊列中調(diào)用了其中一個态坦,就不應(yīng)該再調(diào)用另一個。
RxJava 的觀察者模式大致如下圖
二.例子展示
1.添加依賴
compile 'io.reactivex:rxjava:1.0.14'?
compile 'io.reactivex:rxandroid:1.0.1'
2.創(chuàng)建觀察者
3.創(chuàng)建被觀察者
4.實現(xiàn)訂閱關(guān)系
預(yù)期結(jié)果:當(dāng)點擊控件時棒拂,會依次調(diào)用三次?onNext()?和一次?onCompleted()伞梯。
實際結(jié)果:
這個例子很簡單:事件的內(nèi)容是字符串,而不是一些復(fù)雜的對象帚屉,簡單的學(xué)會的谜诫,復(fù)雜的自己可以去探索,根據(jù)需求場景擴展攻旦。
三.擴展
1.除了?Observer?接口之外喻旷,RxJava 還內(nèi)置了一個實現(xiàn)了?Observer?的抽象類:Subscriber。?Subscriber?對?Observer?接口進行了一些擴展牢屋,但他們的基本使用方式是完全一樣的:
實質(zhì)上掰邢,在 RxJava 的 subscribe 過程中牺陶,Observer?也總是會先被轉(zhuǎn)換成一個?Subscriber?再使用。它們的區(qū)別對于使用者來說主要有兩點:
1)onStart(): 這是?Subscriber?增加的方法辣之。它會在 subscribe 剛開始,而事件還未發(fā)送之前被調(diào)用皱炉,可以用于做一些準(zhǔn)備工作怀估,例如數(shù)據(jù)的清零或重置。這是一個可選方法合搅,默認(rèn)情況下它的實現(xiàn)為空多搀。需要注意的是,如果對準(zhǔn)備工作的線程有要求(例如彈出一個顯示進度的對話框灾部,這必須在主線程執(zhí)行)康铭,?onStart()?就不適用了,因為它總是在 subscribe 所發(fā)生的線程被調(diào)用赌髓,而不能指定線程从藤。要在指定的線程來做準(zhǔn)備工作,可以使用?doOnSubscribe()?方法锁蠕,具體可以在后面的文中看到夷野。
2)unsubscribe(): 這是?Subscriber?所實現(xiàn)的另一個接口?Subscription?的方法,用于取消訂閱荣倾。在這個方法被調(diào)用后悯搔,Subscriber?將不再接收事件。一般在這個方法調(diào)用前舌仍,可以使用?isUnsubscribed()?先判斷一下狀態(tài)妒貌。?unsubscribe()?這個方法很重要,因為在?subscribe()?之后铸豁,?Observable?會持有?Subscriber?的引用灌曙,這個引用如果不能及時被釋放,將有內(nèi)存泄露的風(fēng)險推姻。所以最好保持一個原則:要在不再使用的時候盡快在合適的地方(例如?onPause()?onStop()?等方法中)調(diào)用?unsubscribe()?來解除引用關(guān)系平匈,以避免內(nèi)存泄露的發(fā)生。
2.RxJava 還提供了一些方法用來快捷創(chuàng)建事件隊列藏古,都和 create(OnSubscribe)?的例子是等價的增炭。
just(T...): 將傳入的參數(shù)依次發(fā)送出來。
from(T[])?/?from(Iterable<? extends T>)?: 將傳入的數(shù)組或?Iterable?拆分成具體對象后拧晕,依次發(fā)送出來隙姿。
今天暫時學(xué)習(xí)到這里,下次繼續(xù)厂捞!