Android每周一個(gè)學(xué)習(xí)計(jì)劃——RxJava2.0的學(xué)習(xí)使用

序言:蝸殼已經(jīng)退役一年多了,但是還是抵不住蝸殼在NBA界的影響力,最近NBA流行向“蝸殼挑戰(zhàn)”瘫寝,事情起源于蝸殼給IT和北境之王設(shè)定了新賽季的挑戰(zhàn)爵政,然后眾多球星也紛紛向蝸殼討要挑戰(zhàn)。作為蝸殼的忠實(shí)球迷钢悲,作為一個(gè)IT黨点额,雖說(shuō)向蝸殼也討不到挑戰(zhàn),但是自己還是要對(duì)自己有一個(gè)挑戰(zhàn)的莺琳。

1还棱、RxJava是一個(gè)使用可觀測(cè)的序列來(lái)組成異步的、基于事件的程序的庫(kù)惭等。其特點(diǎn)是異步珍手,觀察者模式。

2、觀察者模式中的觀察者和被觀察者之間的關(guān)系是一對(duì)多琳要,即多個(gè)觀察者可以觀察同一個(gè)被觀察者對(duì)象寡具,在RxJava2中,Observable稱(chēng)之為“被觀察者”稚补,Observer稱(chēng)之為“觀察者”童叠。

3、RxJava2中創(chuàng)建Observable的方式有很多種孔厉,具體如下所示:

(1)拯钻、create()方法:Observable.create(ObservableOnSubscribe<T> source),此種方法是Observable最基本的創(chuàng)建方式撰豺》喟悖可以看到,這里傳入了一個(gè) ObservableOnSubscribe對(duì)象作為參數(shù)污桦,它的作用相當(dāng)于一個(gè)計(jì)劃表亩歹,當(dāng) Observable被訂閱的時(shí)候,ObservableOnSubscribe的subscribe()方法會(huì)自動(dòng)被調(diào)用凡橱,事件序列就會(huì)依照設(shè)定依次觸發(fā)(對(duì)于上面的代碼小作,就是觀察者Observer 將會(huì)被調(diào)用一次 onNext())。這樣稼钩,由被觀察者調(diào)用了觀察者的回調(diào)方法顾稀,就實(shí)現(xiàn)了由被觀察者向觀察者的事件傳遞,即觀察者模式坝撑。

(2)静秆、just()方法:Observable.just(T item),使用just()巡李,將為你創(chuàng)建一個(gè)Observable并自動(dòng)為你調(diào)用onNext()發(fā)射數(shù)據(jù)抚笔。通過(guò)just()方式直接觸發(fā)onNext(),just中傳遞的參數(shù)將直接在Observer的onNext()方法中接收到侨拦。

(3)殊橙、fromArray()方法:Observable.fromArray(T... items),使用fromArray()狱从,該方法的使用以及效果與just()方法是一樣的膨蛮,與just()方法的區(qū)別在于該方法參數(shù)是不限的,而just()方法參數(shù)個(gè)數(shù)是有限的

(4)季研、fromIterable()方法:Observable.fromIterable(Iterable<? extends T> source)敞葛,使用fromIterable(),遍歷集合训貌,發(fā)送每個(gè)item。相當(dāng)于多次回調(diào)onNext()方法,每次傳入一個(gè)item递沪。注意:Collection接口是Iterable接口的子接口豺鼻,所以所有Collection接口的實(shí)現(xiàn)類(lèi)都可以作為Iterable對(duì)象直接傳入fromIterable()方法。

(5)款慨、interval()方法:Observable.interval(long period, TimeUnit unit)儒飒,Observable.interval(long initialDelay, long period, TimeUnit unit),創(chuàng)建一個(gè)按固定時(shí)間間隔發(fā)射整數(shù)序列的Observable檩奠,可用作定時(shí)器桩了。即按照固定period時(shí)間調(diào)用一次onNext()方法。默認(rèn)從0開(kāi)始埠戳,也可以自己設(shè)置開(kāi)始值(initialDelay)井誉。

(6)、range()方法:Observable.range(final int start, final int count)整胃,創(chuàng)建一個(gè)發(fā)射特定整數(shù)序列的Observable颗圣,第一個(gè)參數(shù)為起始值,第二個(gè)為發(fā)送的個(gè)數(shù)屁使,如果為0則不發(fā)送在岂,負(fù)數(shù)則拋異常。上述表示發(fā)射start到count的數(shù)蛮寂。即調(diào)用count次nNext()方法蔽午,依次傳入start-count之間的數(shù)字。

當(dāng)然了酬蹋,還有很多其他的方式創(chuàng)建Observable及老,這里就不一一舉例了:
圖片參照http://www.reibang.com/p/d149043d103a

3、在RxJava中除嘹,有很多的操作符写半,不同的操作符都有不同的用處,以下列舉幾個(gè)比較常用的操作符:

(1)尉咕、map()操作符:map(Function<? super T, ? extends R> mapper)叠蝇,map操作符的作用就是將原始的Observable對(duì)象轉(zhuǎn)換成另一個(gè)Observable對(duì)象,同時(shí)將傳輸?shù)臄?shù)據(jù)進(jìn)行一些靈活的操作年缎,方便Observer獲得想要的數(shù)據(jù)格式進(jìn)行后續(xù)的操作悔捶。

(2)、flatmap()操作符:flatmap(Function<? super T, ? extends ObservableSource<? extends R>> mapper)单芜,flatMap()對(duì)于數(shù)據(jù)的轉(zhuǎn)換比map()更加徹底蜕该,如果發(fā)送的數(shù)據(jù)是集合,flatMap()重新生成一個(gè)Observable對(duì)象洲鸠,并把數(shù)據(jù)轉(zhuǎn)換成Observer想要的數(shù)據(jù)形式堂淡。它可以返回任何它想返回的Observable對(duì)象馋缅。flatMap的另一作用就是加工Observable。

(3)绢淀、filter()操作符:filter(Predicate<? super T> predicate)萤悴,filter是用于過(guò)濾數(shù)據(jù)的,該方法的返回值是一個(gè)boolean類(lèi)型皆的,返回false表示攔截此數(shù)據(jù)不再發(fā)送覆履,返回true則繼續(xù)發(fā)送。

(4)费薄、take()操作符:take(long count)硝全,take用于發(fā)射被觀察者的前count個(gè)item。

(5)楞抡、distinct()操作符:distinct()伟众,distinct操作符的作用是去除重復(fù)的觀察者,一般我們用來(lái)對(duì)數(shù)據(jù)進(jìn)行去重操作拌倍。

(6)赂鲤、delay()操作符:delay(long delay, TimeUnit unit),delay操作符的作用就是延時(shí)發(fā)射Observable里面的事件柱恤,經(jīng)過(guò)delay的時(shí)間才會(huì)收到Observable發(fā)出的事件数初。

(7)、reduce操作符:reduce(BiFunction<T, T, T> reducer)梗顺,reduce操作符可以把一個(gè)被觀察者中的多個(gè)事件進(jìn)行壓縮泡孩,最后發(fā)射壓縮后的事件。我們可以使用reduce操作符做一個(gè)疊加操作活著疊減操作寺谤。

4仑鸥、RxJava最大的一個(gè)特點(diǎn)就是異步,所以當(dāng)然少不了和線程打交道了变屁,RxJava中有一個(gè)線程調(diào)度器Scheduler眼俊,以下列舉幾種常用的線程模式:

(1)、Schedulers.newThread():總是啟用新線程粟关,并在新線程執(zhí)行操作疮胖,因此它可以創(chuàng)建無(wú)限量的工作線程。

(2)闷板、Schedulers.trampoline():主要用于延遲工作任務(wù)的執(zhí)行澎灸。當(dāng)我們想在當(dāng)前線程執(zhí)行一個(gè)任務(wù)時(shí),并不是立即遮晚,trampoline的操作是FIFO隊(duì)列操作性昭,我們可以用trampoline()將它入隊(duì)。trampoline將會(huì)處理它的隊(duì)列并且按序運(yùn)行隊(duì)列中每一個(gè)任務(wù)县遣。

(3)糜颠、Schedulers.io():I/O 操作(讀寫(xiě)文件汹族、讀寫(xiě)數(shù)據(jù)庫(kù)、網(wǎng)絡(luò)信息交互等)所使用的 Scheduler其兴。其效果和 newThread() 差不多鞠抑,區(qū)別在于 io() 的內(nèi)部實(shí)現(xiàn)是用一個(gè)無(wú)數(shù)量上限的線程池,可以重用空閑的線程忌警,因此多數(shù)情況下 io() 比 newThread() 更有效率。不要把計(jì)算工作放在 io() 中秒梳,可以避免創(chuàng)建不必要的線程法绵。

(4)、AndroidSchedulers.mainThread():這是Android特有的線程酪碘,UI主線程朋譬。

通過(guò)上述幾種線程控制,我們就能實(shí)現(xiàn)異步操作了兴垦,subscribeOn(): 指定Observable(被觀察者)所在的線程徙赢,或者叫做事件產(chǎn)生的線程。observeOn(): 指定Observer(觀察者)所運(yùn)行在的線程探越,或者叫做事件消費(fèi)的線程狡赐。

5、RxJava的觀察者能收到三種事件钦幔,onNext(基本事件)枕屉,onComplete(完成事件),onError(異常事件)鲤氢。被觀察者可以發(fā)送無(wú)限個(gè)onNext事件搀擂,但是只能發(fā)送一個(gè)onComplete或者onError事件,觀察者也可以接收無(wú)限個(gè)onNext事件卷玉,也只能接收一個(gè)onComplete或者onError事件哨颂,為什么這里說(shuō)或者呢,因?yàn)閛nComplete事件和onError事件屬于互斥事件相种,二者只能出現(xiàn)其一威恼,而且當(dāng)這兩個(gè)事件被發(fā)送或者接收之后就不能再發(fā)送事件和接收事件了。

6蚂子、Rxjava中沃测,還有一個(gè)很大的變化就是Backpressure(背壓),何為背壓食茎,就是觀察者來(lái)不及處理被觀察者發(fā)出的事件(產(chǎn)生事件的速度大于處理事件的速度)蒂破,導(dǎo)致事件被無(wú)限堆積,最后產(chǎn)生異常别渔。在2.0版本中有一個(gè)專(zhuān)門(mén)針對(duì)背壓的被觀察者Flowable附迷,分別有以下幾種策略:

(1)惧互、ERROR策略:在異步調(diào)用時(shí),RxJava中有個(gè)緩存池喇伯,用來(lái)緩觀察者處理不了暫時(shí)緩存下來(lái)的數(shù)據(jù)喊儡,緩存池的默認(rèn)大小為128,即只能緩存128個(gè)事件稻据“拢回調(diào)的時(shí)候會(huì)傳給我們一個(gè)Subscription對(duì)象,調(diào)用該對(duì)象的request(long n)方法可以向被觀察者申請(qǐng)消費(fèi)的事件數(shù)捻悯,調(diào)用該對(duì)象的cancel()方法也可以切斷被觀察者和觀察者之間的聯(lián)系匆赃,這一點(diǎn)和Disposable一樣。無(wú)論request()中傳入的數(shù)字比128大或小今缚,緩存池中在剛開(kāi)始都會(huì)存入128個(gè)事件算柳。當(dāng)然如果本身并沒(méi)有這么多事件需要發(fā)送,則不會(huì)存128個(gè)事件姓言。在ERROR策略下瞬项,如果緩存池溢出,就會(huì)立刻拋出MissingBackpressureException異常何荚。

(2)囱淋、BUFFER策略:剛才我們說(shuō)到RxJava中有個(gè)緩存池,默認(rèn)的大小是只能緩存128個(gè)事件餐塘,BUFFER策略就是將這個(gè)緩存池變大绎橘,即緩存的事件會(huì)更多。因此這種策略比較耗內(nèi)存唠倦,會(huì)導(dǎo)致OOM称鳞,所以不推薦使用。

(3)稠鼻、DROP策略:當(dāng)觀察者處理不了事件冈止,就丟棄。觀察者通過(guò)request()傳入其需求n候齿,然后被觀察者把n個(gè)事件傳遞給觀察者供其消費(fèi)熙暴。其他消費(fèi)不掉的事件就丟掉。

(4)慌盯、LATEST策略:LATEST與DROP功能基本一致周霉。唯一的區(qū)別就是LATEST總能使觀察者能夠接收到被觀察者產(chǎn)生的最后一個(gè)事件。

參考:手把手教你使用 RxJava 2.0系列

相關(guān)代碼已上傳至GitHub傳送門(mén)

每周一個(gè)學(xué)習(xí)計(jì)劃亚皂,未完待續(xù)......

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末俱箱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子灭必,更是在濱河造成了極大的恐慌狞谱,老刑警劉巖乃摹,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異跟衅,居然都是意外死亡孵睬,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)伶跷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)掰读,“玉大人,你說(shuō)我怎么就攤上這事叭莫×字В” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵食寡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我廓潜,道長(zhǎng)抵皱,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任辩蛋,我火速辦了婚禮呻畸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘悼院。我一直安慰自己伤为,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布据途。 她就那樣靜靜地躺著绞愚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颖医。 梳的紋絲不亂的頭發(fā)上位衩,一...
    開(kāi)封第一講書(shū)人閱讀 51,215評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音熔萧,去河邊找鬼糖驴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛佛致,可吹牛的內(nèi)容都是我干的贮缕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼俺榆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼感昼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起罐脊,我...
    開(kāi)封第一講書(shū)人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤抑诸,失蹤者是張志新(化名)和其女友劉穎烂琴,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蜕乡,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奸绷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了层玲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片号醉。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖辛块,靈堂內(nèi)的尸體忽然破棺而出畔派,到底是詐尸還是另有隱情,我是刑警寧澤润绵,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布线椰,位于F島的核電站,受9級(jí)特大地震影響尘盼,放射性物質(zhì)發(fā)生泄漏憨愉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一卿捎、第九天 我趴在偏房一處隱蔽的房頂上張望配紫。 院中可真熱鬧,春花似錦午阵、人聲如沸躺孝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)植袍。三九已至,卻和暖如春籽懦,著一層夾襖步出監(jiān)牢的瞬間奋单,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工猫十, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留览濒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓拖云,卻偏偏與公主長(zhǎng)得像贷笛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宙项,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容