rxjava essentials中文翻譯是對(duì)Ivan.Morgillo所寫一書僅供交流學(xué)_第1頁
rxjava essentials中文翻譯是對(duì)Ivan.Morgillo所寫一書僅供交流學(xué)_第2頁
rxjava essentials中文翻譯是對(duì)Ivan.Morgillo所寫一書僅供交流學(xué)_第3頁
rxjava essentials中文翻譯是對(duì)Ivan.Morgillo所寫一書僅供交流學(xué)_第4頁
rxjava essentials中文翻譯是對(duì)Ivan.Morgillo所寫一書僅供交流學(xué)_第5頁
免費(fèi)預(yù)覽已結(jié)束,剩余154頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

arningReactiveProgramming》?!禦xJavaEssentials》翻譯中文版RX-from.NETto本章帶你進(jìn)入reactive的世界。我們會(huì)比較reactive法和傳統(tǒng)方法,進(jìn)而探索它們之間的相似和不同的地WhyoReactive本章會(huì)利用我們所學(xué)的知識(shí)來創(chuàng)建第一個(gè)reactiveAndroid應(yīng)用Filtering的值,如何獲得一個(gè)有限的數(shù)值,如何處理溢出的場(chǎng)景,以及有用的技巧。Transforming本章將講述如何通過變換Observable序列來創(chuàng)建出我們所需要的bining本章將研究與函數(shù)結(jié)合,同時(shí)也會(huì)學(xué)到當(dāng)創(chuàng)建我們想要的Observable時(shí)又如何與多個(gè)Observable協(xié)同工作Schedulers-DefeatingtheAndroidMainThread本章將介紹如何使用RxJavaSchedulers處理多線程和并發(fā)編程。我們也將用reactive的方式來創(chuàng)建網(wǎng)絡(luò)操RESTinpeace-RxJavaand本章你如何讓Square公司的Retrofit和RxJava結(jié)合來一起使用,來創(chuàng)建一個(gè)更高效的REST客戶端程序?yàn)榱四軌蜻\(yùn)行例子,你需要一個(gè)標(biāo)準(zhǔn)的Android開發(fā)環(huán)境AndroidStudio或 lijAndroidJava作為一個(gè)純粹的Java開發(fā)者,當(dāng)你接觸RxJava時(shí),很明顯你需要一個(gè)你喜歡Java編輯器和一個(gè)標(biāo)準(zhǔn)的JavaJDK環(huán)境。這本一些圖表來自ht 和。如果你是一名有經(jīng)驗(yàn)的Java開發(fā)者,reactive編程將會(huì)在后端系統(tǒng)中給你一種新的學(xué)習(xí)擴(kuò)展和并發(fā)的方式,而這不需要更換開發(fā)語言。這本書將幫助你學(xué)習(xí)RxJava的方面,也能幫助你克服Android平臺(tái)局限性從而創(chuàng)建一個(gè)基于事件驅(qū)動(dòng)的,響應(yīng)式的,流暢體驗(yàn)的Android應(yīng)用。在這本書中,你會(huì)發(fā)現(xiàn)許多用來區(qū)分不同信息的文本樣式,這列舉這些樣式的一些例子和對(duì)他們釋義的說itterhandles:“正如你看到的那樣:zip()有三個(gè)參數(shù):兩個(gè)Observable和一個(gè)Func2”如下面的一塊代碼publicpublicObservable<List<User>>getMostPopularSOusers(inthowmany){returnmStackExchangeService}當(dāng)我們想對(duì)代碼塊的某一部分引起你的注意時(shí),會(huì)在對(duì)應(yīng)的那一行或列設(shè)置為publicpublicObservable<List<User>>getMostPopularSOusers(inthowmany){returnmStackExchangeService }在文本中:“WewilljustneedafancyprogressbarandaDOWNLOADbutton.類似這樣的是警告或者出現(xiàn)在框中的重要Tip似這樣的是提示和技發(fā)送郵件到 在你的郵件中要提到書的標(biāo)題如果你有擅長(zhǎng)的話題并且你對(duì)寫作感或者想出書的話,可以看我們作者指南:http: 的賬戶中所有你Packt的的樣例代碼,如果你從別處購(gòu)買這本書的話,你可以:http: /support并將文件用附件直接發(fā)給你。說RxJavaEssentials中文翻譯 交流學(xué)習(xí)使用,嚴(yán)禁商業(yè)用途 請(qǐng)聯(lián)系作者yuxingxin前 第1章RxJavaEssentials中文翻譯版..........8第1章本書內(nèi)容有......第1章學(xué)習(xí)這本書你需要做的:......第1章這本書適合哪些人看.........第1章一些約定........第1章讀者反饋........第1章樣例代碼........說明第2章RXNET到RxJava.....微軟響應(yīng)式擴(kuò)展來到Java世界-NetflixRxJavaRxJava的與眾不同之處總結(jié)第3章為什么是Observables?........觀察者模式你什么時(shí)候使用觀察者模RxJava觀察者模式工具包Observable...................................Subject=Observable+Observer.........................總結(jié)第4章向響應(yīng)式世界問好.....啟動(dòng)引擎工具我們的第一個(gè)Observable從列表創(chuàng)建一個(gè)Observable再多幾個(gè)例子總結(jié)第5章過濾Observables......過濾序列獲取我們需要的數(shù)據(jù)有且僅有一次Firstandlast.................................SkipandSkipLast................................ElementAt....................................Sampling....................................Timeout.....................................Debounce....................................總結(jié)第6章轉(zhuǎn)換Observables......*mapGroupBy.....................................Buffer.....................................Window.....................................Cast......................................總結(jié)第7章組合Observables......Merge...................................... combineLatest..................................And,Then和WhenSwitch.....................................StartWith....................................總結(jié)第8章Schedulers-解決Android主線程問題........StrictMode...................................避免阻塞I/O的操Schedulers...................................非阻塞I/O操SubscribeOnandObserveOn............................處理耗時(shí)的任務(wù)執(zhí)行網(wǎng)絡(luò)任務(wù)總結(jié)第9章與REST無縫結(jié)合-RxJava和Retrofit......項(xiàng)目目標(biāo)Retrofit....................................創(chuàng)建RecyclerViewAdapter總結(jié)11RxJavaEssentials中文翻譯版1RxJavaEssentials|arningReactiveProgramming》?!禦xJavaEssentials》翻譯中文1|1本章帶你進(jìn)入reactive的世界。我們會(huì)比較reactive法和傳統(tǒng)方法,進(jìn)而探索它們之間的相似和不同的地2.Why3.oReactive本章會(huì)利用我們所學(xué)的知識(shí)來創(chuàng)建第一個(gè)reactiveAndroid應(yīng)用4.Filtering的值,如何獲得一個(gè)有限的數(shù)值,如何處理溢出的場(chǎng)景,以及有用的技巧。5.Transforming本章將講述如何通過變換Observable序列來創(chuàng)建出我們所需要的序bining本章將研究與函數(shù)結(jié)合,同時(shí)也會(huì)學(xué)到當(dāng)創(chuàng)建我們想要的Observable時(shí)又如何與多個(gè)Observable協(xié)同工作7.Schedulers-DefeatingtheAndroidMainThread本章將介紹如何使用RxJavaSchedulers處理多線程和并發(fā)編程。我們也將用reactive的方式來創(chuàng)建網(wǎng)絡(luò)操本 你如何讓Square公司的Retrofit和RxJava結(jié)合來一起使用,來創(chuàng)建一個(gè)更高效的REST客戶端程序11|1為了能夠運(yùn)行例子,你需要一個(gè)標(biāo)準(zhǔn)的Android開發(fā)環(huán)境AndroidStudio或InlijAndroidJava作為一個(gè)純粹的Java開發(fā)者,當(dāng)你接觸RxJava時(shí),很明顯你需要一個(gè)你喜歡Java編輯器和一個(gè)標(biāo)準(zhǔn)的JavaJDK環(huán) 11|1如果你是一名有經(jīng)驗(yàn)的Java開發(fā)者,reactive編程將會(huì)在后端系統(tǒng)中給你一種新的學(xué)習(xí)擴(kuò)展和并發(fā)的方式,而這不需要更換開發(fā)語言。這本書將幫助你學(xué)習(xí)RxJava的方面,也能幫助你克服Android平臺(tái)局限性從而創(chuàng)建一個(gè)基于事件驅(qū)動(dòng)的,響應(yīng)式的,流暢體驗(yàn)的Android應(yīng)用。11|1在這本書中,你會(huì)發(fā)現(xiàn)許多用來區(qū)分不同信息的文本樣式,這列舉這些樣式的一些例子和對(duì)他們釋義的說明itterhandles:“正如你看到的那樣:zip()有三個(gè)參數(shù):兩個(gè)Observable和一個(gè)Func2”如下面的一塊代碼publicpublicObservable<List<User>>getMostPopularSOusers(inthowmany){returnmStackExchangeService}當(dāng)我們想對(duì)代碼塊的某一部分引起你的注意時(shí),會(huì)在對(duì)應(yīng)的那一行或列設(shè)置為publicpublicObservable<List<User>>getMostPopularSOusers(inthowmany){returnmStackExchangeService }在文本中:“WewilljustneedafancyprogressbarandaDOWNLOADbutton.類似這樣的是警告或者出現(xiàn)在框中的重要Tip似這樣的是提示和技11|1發(fā)送郵件到 在你的郵件中要提到書的標(biāo)題如果你有擅長(zhǎng)的話題并且你對(duì)寫作感或者想出書的話,可以看我們作者指南:http: 第1章樣例代碼|第1章樣例代 的賬戶中所有你Packt的的樣例代碼,如果你從別處購(gòu) 說RxJavaEssentials中文翻譯 交流學(xué)習(xí)使用,嚴(yán)禁商業(yè)用途 請(qǐng)聯(lián)系作者yuxingxin22RX-從.NET到響應(yīng)式編程是一種基于異步數(shù)據(jù)流概念的編程模式。數(shù)據(jù)流就像一條河:它可以被觀測(cè),被過濾,作,或者響應(yīng)式編程的一個(gè)關(guān)鍵概念是事件。事件可以被等待,可以觸發(fā)過程,也可以觸發(fā)其它事件。事件是唯一的以合適的方式將我們的現(xiàn)實(shí)世界映射到我們的軟件中:如果屋里太熱了我們就打開一扇窗戶。同樣的,當(dāng)我們更改電子表(變化的)中的一些數(shù)值時(shí),我們需要更新整個(gè)表格或者我們的機(jī)器人碰到墻時(shí)會(huì)轉(zhuǎn)彎(響應(yīng)事件)。應(yīng)。在上,軟件之所以是事件驅(qū)動(dòng)并響應(yīng)的是因?yàn)楝F(xiàn)實(shí)生活也是如此。微軟響應(yīng)式擴(kuò)函數(shù)響應(yīng)式編程是一個(gè)來自90年代后期受微軟的一名計(jì)算機(jī)科學(xué)家ErikMeijer啟發(fā)的思想,用來設(shè)計(jì)和開發(fā)微軟Rx是微軟.NET的一個(gè)響應(yīng)式擴(kuò)展。Rx借助可觀測(cè)的序列提供一種簡(jiǎn)單的方式來創(chuàng)建異步的,基于事件驅(qū)動(dòng)的程下表列出的與.NET舉相關(guān)的.NET.NETpush方法把這個(gè)問題逆轉(zhuǎn)了:取而代之的是不再等待結(jié)果,開發(fā)者只是簡(jiǎn)單的請(qǐng)求結(jié)果,而當(dāng)它返回時(shí)得到一個(gè)通知即可。開發(fā)者對(duì)即將發(fā)生的事件提供一個(gè)清晰的響應(yīng)鏈。對(duì)于每一個(gè)事件,開發(fā)者都作出相應(yīng)的響應(yīng);例如,用戶被要求登錄的時(shí)候,提交一個(gè)攜帶他的用戶名和的表單。應(yīng)用程序執(zhí)行登錄的網(wǎng)絡(luò)請(qǐng)求,接下來將要發(fā)生的情況有:顯示一個(gè)成功的信息,并保存用戶的個(gè)人信顯示一個(gè)錯(cuò)誤的信正如你用push方法所看到的,開發(fā)者不需要等待結(jié)果。而是在結(jié)果返回時(shí)通知他。在這期間,他可以做他顯示一個(gè)進(jìn)度為下次登錄保存用戶名和預(yù)加載一些他認(rèn)為登錄成功后需要耗時(shí)處理的來到JavaNetflixNetflix在2012年開始他們的架構(gòu)要滿足他們龐大的用戶群體已經(jīng)變得步履維艱。因此他們決定重新設(shè)計(jì)架構(gòu)來減少REST調(diào)用的次數(shù)。取代幾十次的REST調(diào)用,而是讓客戶端自己處理需要的數(shù)據(jù),他們決定基于客戶端需求創(chuàng)建一個(gè)專門優(yōu)化過的REST調(diào)用。為了實(shí)現(xiàn)這一目標(biāo),他們決定嘗試響應(yīng)式,開始將.NETRx遷移到JVM上面。他們不想只基于Java語言;而是整個(gè)J2013年二月份,BenChristensenJafarHusain發(fā)在Netflix技術(shù)博客的一篇文章第一次向世界展示了RxJava。易于并發(fā)從而更好的利用服務(wù)器的能易于有條件的異步執(zhí)行一種更好的方式來避免回調(diào)一種響應(yīng)式方法正如.NET,RxJavaObservable是push迭代的等價(jià)體,即pull。pull方法是阻塞并等待的方法:消費(fèi)者從pulpush方法作用于訂閱和響應(yīng):消費(fèi)者訂閱新值的發(fā)射,當(dāng)它們可用時(shí)生產(chǎn)者push這些新值并通知消費(fèi)者。在這一點(diǎn)上,消費(fèi)者消費(fèi)了它們。push方法很明顯更靈活,因?yàn)閺倪壿嫼蛯?shí)踐的觀點(diǎn)來看,開發(fā)者只需忽略他需要的數(shù)據(jù)是來自同步還是異步;他的代碼將仍然起作用。RxJava的與眾不同之從純Java的觀點(diǎn)看,RxJavaObservable類源自于經(jīng)典的GangOfFour的觀察者模式。生產(chǎn)者在沒有數(shù)據(jù)可用時(shí)能夠發(fā)出信號(hào)通知 pleted()事件生產(chǎn)者在發(fā)生錯(cuò)誤時(shí)能夠發(fā)出信號(hào)通知:onError()事件RxJavaObservables能夠組合而不是嵌套,從而避免開發(fā)者陷入回調(diào)Observables和Iterables共用一個(gè)相似的API:我們?cè)贗terable可以執(zhí)行的許多操作也都同樣可以在上執(zhí)行。當(dāng)然,由于Observables流的本質(zhì),沒有如Iterable.remove()這樣相應(yīng)的方法TFuture<T>Observable<T>從語義的角度來看,RxJava就是.NETRx。從語法的角度來看,Netflix考慮到了對(duì)應(yīng)每個(gè)Rx方法,保留了Java代碼總下一章 學(xué)習(xí)到Observables是什么,以及如何創(chuàng)建它并把響應(yīng)式編程應(yīng)用到我們的日常編碼中去33可以被測(cè)試、復(fù)用和。設(shè)計(jì)這種系統(tǒng)就帶來一個(gè)棘手的影響:相關(guān)對(duì)象之間的統(tǒng)一。在SmalltalkMVC架構(gòu)中,創(chuàng)建模式的第一個(gè)例子就是用來解決這個(gè)問題的。用戶界面框架提供一種途徑使UI元素在這本暢銷的四人組編寫的《設(shè)計(jì)模式——可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書中,觀察者模式是最有名的設(shè)計(jì)模式之一。它是一種行為模式并提供一種以一對(duì)多的依賴來綁定對(duì)象的方法:即當(dāng)一個(gè)對(duì)象發(fā)生變化時(shí),依賴它的所有對(duì)象都會(huì)被通知并且會(huì)自動(dòng)更新。在本章中,會(huì)對(duì)觀察者模式有一個(gè)概述,它是如何實(shí)現(xiàn)的以及如何用RxJava來擴(kuò)展,Observable是什觀察者模在今天,觀察者模式是出現(xiàn)的最常用的軟件設(shè)計(jì)模式之一。它基于subject這個(gè)概念。subject是一種特殊在上一章中,我們看到了電子表單的例子?,F(xiàn)在我們可以展開這個(gè)例子講,展示一個(gè)更復(fù)雜的場(chǎng)景。讓我們考慮這樣一個(gè)填著賬戶數(shù)據(jù)的電子表單。我們可以把這些數(shù)據(jù)比作一張表,或者是3D柱狀圖,或者是餅狀圖。它們中每一的意義都取決于同一組要展示的數(shù)據(jù)。每一個(gè)都是一個(gè)觀察者,都依賴于那一個(gè)subject,部信息。3D柱狀圖這個(gè)類、餅狀圖類、表這個(gè)類以及這些數(shù)據(jù)的類是完全解耦的:它們彼此相互獨(dú)立復(fù)用,但也能協(xié)同工作。這些表示類彼此不清楚對(duì)方,但是正如它們所做的:它們知道在哪能找到它們需要展示的信息,它們也知道一旦數(shù)據(jù)發(fā)生變化就通知需要更新數(shù)據(jù)表示的那個(gè)類。這有一描述了Subject/Observer的關(guān)系是怎樣的一對(duì)多的關(guān)系上面這展示了一個(gè)Subject為3個(gè)Observers提供服務(wù)。很明顯,沒有理由去限制Observers要,一個(gè)Subject可以有無限多個(gè)Observers,當(dāng)subject狀態(tài)發(fā)生變化時(shí),這些Observers中的每一個(gè)都會(huì)收到通知。你什么時(shí)候使用觀察者模觀察者模式很適合下面這些場(chǎng)景中的任何一個(gè)當(dāng)你的架構(gòu)有兩個(gè)實(shí)體類,一個(gè)依賴另一個(gè),你想讓它們互不影響或者是獨(dú)立復(fù)用它們當(dāng)一個(gè)變化的對(duì)象通知那些與它自身變化相關(guān)聯(lián)的未知數(shù)量的對(duì)象當(dāng)一個(gè)變化的對(duì)象通知那些無需推斷具體類型的對(duì)象RxJava觀察者模式工具在RxJava的世界里,我們有四種角色:*Observable*Observer*Subscriber*Subjects當(dāng)我們異步執(zhí)行一些復(fù)雜的事情,Java提供了傳統(tǒng)的類,例如Thread、 來處理這些問題。當(dāng)復(fù)雜度提升,這些方案就會(huì)變得麻煩和難以。最糟糕的是,它們都不支持鏈?zhǔn)秸{(diào)用RxJavaObservables被設(shè)計(jì)用來解決這些問題。它們靈活,且易于使用,也可以鏈?zhǔn)秸{(diào)用,并且可以作用于單個(gè)結(jié)果程序上,更有甚者,也可以作用于序列上。無論何時(shí)你想發(fā)射單個(gè)標(biāo)量值,或者一連串值,甚至是無窮個(gè)數(shù)值流,你都可以使用Observable。bleasync/push與Iterablesync/pull相關(guān)聯(lián)起來。檢索數(shù)T發(fā)現(xiàn)錯(cuò)throws完 使用Iterable時(shí),消費(fèi)者從生產(chǎn)者那里以同步的方式得到值,在這些值得到之前線程處于阻塞狀態(tài)。相反,使用Observable時(shí),生產(chǎn)者以異步的方式把值推給觀察者,無論何時(shí),這些值都是可用的。這種方法之所以更靈活是因?yàn)榧幢阒凳峭交虍惒椒绞降竭_(dá),消費(fèi)者在這兩種場(chǎng)景都可以根據(jù)自己的需要來處理。為了更好地復(fù)用Iterable接口,RxJavaObservable類擴(kuò)展了GOF觀察者模式的語義。引入了兩個(gè)新的接口:*onCompleted()即通知觀察者Observable沒有的數(shù)據(jù)。*onError()即觀察者有錯(cuò)誤出現(xiàn)了。熱Observables和冷從發(fā)射物的角度來看,有兩種不同的Observables:熱的和冷的。一個(gè)"熱"的Observable典型的只要一創(chuàng)建完就開始發(fā)射數(shù)據(jù),因此所有后續(xù)訂閱它的觀察者可能從序列中間的某個(gè)位置開始接受數(shù)據(jù)(有一些數(shù)據(jù)錯(cuò)過了)個(gè)"冷"的Observable會(huì)一直等待,直到有觀察者訂閱它才開始發(fā)射數(shù)據(jù),因此這個(gè)觀察者可以確保會(huì)收到整個(gè)數(shù)據(jù)序列。創(chuàng)建一個(gè)在接下來的小節(jié)中將討論Observables提供的兩種創(chuàng)建Observable的方法create()方法使開發(fā)者有能力從頭開始創(chuàng)建一個(gè)Observable。它需要一個(gè)OnSubscribe對(duì)象,這個(gè)對(duì)象繼承Action當(dāng)觀察者訂閱我們的Observable時(shí),它作為一個(gè)參數(shù)傳入并執(zhí)行callObservable.OnSubscribe<Object>(){publicvoidcall(Subscriber<?superObject>subscriber)}ObservableObservable<Integer>observableString=Observable.create(new{publicvoidcall(Subscriber<?superInteger>{for(inti=0;i<5;i++){}}SubscriptionsubscriptionPrint=observableString.subscribe(new{public {System.out.println("Observable}publicvoidonError(Throwable{System.out.println("Oh,no!Somethingwronghappened!}publicvoidonNext(Integer{System.out.println("Itemis"+}例子故意寫的簡(jiǎn)單,是因?yàn)榧幢闶悄愕谝淮我姷絉xJava的操作,讓你明白接下來要發(fā)生什么我們創(chuàng)建一個(gè)新的Observable<Integer>,它執(zhí)行了5個(gè)元素的for循環(huán),一個(gè)接一個(gè)的發(fā)射他們,最后完另一方面,我們訂閱了Observable,返回一個(gè)Subscription。一旦我們訂閱了,我們就開始接受整數(shù),并一個(gè)接一個(gè)的打印出它們。我們并不知道要接受多少整數(shù)。事實(shí)上,我們也無需知道是因?yàn)槲覀優(yōu)槊糠N場(chǎng)景都提供對(duì)應(yīng)的處理操作:*如果我們接收到了整數(shù),那么就打印它。*如果序列結(jié)束,我們就打印一個(gè)關(guān)閉的序列信息。*如果錯(cuò)誤發(fā)生了,我們就打印一個(gè)錯(cuò)誤信在下面的例子代碼中,我們從一個(gè)已有的列表中創(chuàng)建一個(gè)Observable序列ListList<Integer>items=newArrayList<Integer>();Observable<Integer>observableString=SubscriptionsubscriptionPrint=observableString.subscribe(new{public {System.out.println("Observable}publicvoidonError(Throwable{System.out.println("Oh,no!Somethingwronghappened!}publicvoidonNext(Integer{System.out.println("Itemis"+}輸出的結(jié)果和上面的例子絕對(duì)是一樣from()創(chuàng)建符可以從一個(gè)列表/數(shù)組來創(chuàng)建Observable,并一個(gè)接一個(gè)的從列表/數(shù)組中發(fā)射出來每一個(gè)對(duì)者也可以從JavaFuture類來創(chuàng)建Observable,并發(fā)射Future對(duì)象的.get()方法返回的結(jié)果值。傳入Future為參數(shù)時(shí),我們可以指定一個(gè)超時(shí)的值。Observable將等待來自Future回,Observable將會(huì)觸發(fā)onError()方法通知觀察者有錯(cuò)誤發(fā)生了如果我們已經(jīng)有了一個(gè)傳統(tǒng)的Java函數(shù),我們想把它轉(zhuǎn)變?yōu)橐粋€(gè)Observable又改怎么辦呢?我們可以用e()方法,正如我們先前看到的,或者我們也可以像下面那樣使用以此來省去許多模板代碼ObservableObservable<String>observableString= SubscriptionsubscriptionPrint=observableString.subscribe(new{public {System.out.println("Observable}publicvoidonError(Throwable{System.out.println("Oh,no!Somethingwrong}publicvoidonNext(String{}方法比較簡(jiǎn)單,像這樣privateprivateoWorld(){return oWorld";不管怎樣,它可以是我們想要的任何函數(shù)。在剛才的例子中,我們一旦創(chuàng)建了Observable,just執(zhí)行函數(shù),當(dāng)just()方法可以傳入一到九個(gè)參數(shù),它們會(huì)按照傳入的參數(shù)的順序來發(fā)射它們。just()方法也可以接受列表數(shù)組,就像from()方法,但是它不會(huì)迭代列表發(fā)射每個(gè)值,它將會(huì)發(fā)射整個(gè)列表。通常,當(dāng)我們想發(fā)射一組已經(jīng)定義好的值時(shí)會(huì)用到它。但是如果我們的函數(shù)不是時(shí)變性的,我們可以用just來創(chuàng)建一個(gè)更有組織性和可測(cè)性的代碼庫。最后注意just()創(chuàng)建符,它發(fā)射出值后,Observable正常結(jié)束,在上面那個(gè)例子中,我們會(huì)在控制臺(tái)打印出兩條信息:“oWorld”和“Observablecompleted”。Observable.empty(),Observable.never(),和當(dāng)我們需要一個(gè)Observable毫無理由的不再發(fā)射數(shù)據(jù)正常結(jié)束時(shí),我們可以使用empty()。我們可以使用r()創(chuàng)建一個(gè)不發(fā)射數(shù)據(jù)并且也不會(huì)結(jié)束的Observable。我們也可以使用throw()創(chuàng)建一個(gè)不發(fā)射數(shù)據(jù)并且Subject=Observable+subject是一個(gè)神奇的對(duì)象,它可以是一個(gè)Observable同時(shí)也可以是一個(gè)Observer:它作為連接這兩個(gè)世界的一一旦Subject訂閱了Observable,它將會(huì)觸發(fā)Observable開始發(fā)射。如果原始的Observable訂閱一個(gè)“熱”的Observable變量產(chǎn)生影響。RxJava提供四種不同的Subject:*PublishSubject*BehaviorSubject*ReplaySubject.*Publish是Subject的一個(gè)基礎(chǔ)子類。讓我們看看用PublishSubject實(shí)現(xiàn)傳統(tǒng)的 oWorldPublishSubjectPublishSubject<String>stringPublishSubject=SubscriptionsubscriptionPrint=stringPublishSubject.subscribe(new{public {System.out.println("Observable}publicvoidonError(Throwable{System.out.println("Oh,no!Somethingwrong}publicvoidonNext(String{} o在剛才的例子中,我們創(chuàng)建了一個(gè)PublishSubject,用create()方法發(fā)射一個(gè)String值,然后我們訂閱了ishSubject。此時(shí),沒有數(shù)據(jù)要發(fā)送,因此我們的觀察者只能等待,沒有阻塞線程,也沒有消耗資源。就在這隨時(shí)準(zhǔn)備從subject接收值,如果subject沒有發(fā)射值那么我們的觀察者就會(huì)一直在等待。再次的是,無需擔(dān)心:觀察者知道在每個(gè)場(chǎng)景中該做什么,我們不用擔(dān)心什么時(shí)候是因?yàn)樗琼憫?yīng)式的:系統(tǒng)會(huì)響應(yīng)。我們并不關(guān)心它什么時(shí)候響應(yīng)。我們只關(guān)心它響應(yīng)時(shí)該做什么。 oWorld”,它觸發(fā)了觀察者的onNext()方法,讓我們?cè)诳刂婆_(tái)打印出“oWorld”信息。讓我們看一個(gè)更復(fù)雜的例子。話說我們有一個(gè)private的Observable,外部不能。Observable在它生命首先,我們創(chuàng)建一個(gè)新的PublishSubject來響應(yīng)它的onNext()方法,并且外部也可以它finalfinalPublishSubject<Boolean>subject=subject.subscribe(new{public pleted()}publicvoidonError(Throwablee)}publicvoidonNext(Boolean{System.out.println("Observable}然后,我們創(chuàng)建“私有”的Observable,只有subject才可以的到ObservableObservable.create(new{publicvoidcall(Subscriber<?superInteger>{for(inti=0;i<5;i++){}} pleted(new{publicvoid{}Observable.create()方法包含了我們熟悉的for循環(huán),發(fā)射數(shù)字 pleted()方法指定當(dāng)Observable結(jié)時(shí)要做什么事情:在subject上發(fā)射true。最后,我們訂閱了Observable。很明顯,空的subscribe()為了開啟Observable,而不用管已發(fā)出的任何值,也不用管完成事件或者錯(cuò)誤事件。為了這個(gè)例子我們需要它像這樣。簡(jiǎn)單的說,BehaviorSubject會(huì)首先向他的訂閱者發(fā)送截至訂閱前的一個(gè)數(shù)據(jù)對(duì)象(或初始值),然后正常發(fā)BehaviorSubjectBehaviorSubject<Integer>behaviorSubject=射的數(shù)據(jù),所以它需要一個(gè)初始值。ReplaySubject會(huì)緩存它所訂閱的所有數(shù)據(jù),向任意一個(gè)訂閱它的觀察者重ReplaySubjectReplaySubject<Integer>replaySubject=當(dāng)Observable完成時(shí)AsyncSubject只會(huì)發(fā)布最后一個(gè)數(shù)據(jù)給已經(jīng)訂閱的每一個(gè)觀察AsyncSubjectAsyncSubject<Integer>asyncSubject=總下一章中,創(chuàng)建第一個(gè)基于RxJava的Android應(yīng)用程序,學(xué)習(xí)如何檢索數(shù)據(jù)來填充listview,以及探索如何44在上一章中,我們對(duì)觀察者模式有個(gè)理論上的快速概述。我們也看了從頭開始、從列表、或者從已經(jīng)存在的函數(shù)來創(chuàng)建Observables。在本章中,用我們學(xué)到的來創(chuàng)建我們第一個(gè)響應(yīng)式Android應(yīng)用程序。首先,我們需要搭建環(huán)境,導(dǎo)入需要的庫和有用的庫。然后創(chuàng)建一個(gè)簡(jiǎn)單的應(yīng)用程序,在不同的flavors中包含幾個(gè)用Java填充的RecycleViewitems。啟動(dòng)使用InliJIDEA/AndroidStudio來創(chuàng)建這個(gè)工程,因此你會(huì)對(duì)截圖看起來比較熟悉如果你想用AndroidStudio創(chuàng)建一個(gè)新的工程,通常你可以參考文檔:/training/basics/firstapp/creating-依很明顯 使用Gradle來管理我們的依賴列表。我們的build.gradble文件看起來像這樣正如你看到的我們引入了RxAndroid。RxAndroid是RxJava的增強(qiáng)版,尤其是針對(duì)Android設(shè)計(jì)的RxAndroid是RxJava的一部分。它基于RxJava1.0.x,在普通的RxJava基礎(chǔ)上添加了幾個(gè)有用的類。大多數(shù)情況下,它為Android添加了特殊的調(diào)度器。在第七章Schedulers-DefeatingtheAndroidMainThreadIssue再討論它。工出于實(shí)用,我們引入了LombokButterKnife。這兩個(gè)可以幫助我們?cè)贏ndroid應(yīng)用程序中少寫許多模板類代Lombok使用注解的方式為你生成許多代碼。使用它老生成getter/setter、toString()、equals()、hashCode()。它借助于Gradle依賴和一個(gè)AndroidStudio插件。ButterButterKnife使用注解的方式來幫助我們免去寫findViewById()和設(shè)置點(diǎn)擊的痛苦。至于Lombok,我們可以通過導(dǎo)入依賴和安裝AndroidStudio插件來獲得更好的體驗(yàn)。最后,我們導(dǎo)入Retrolambda,是因?yàn)槲覀冮_發(fā)的Android是基于Java1.6,然后我們可以借助它來實(shí)現(xiàn)Java8La我們的第一個(gè)在我們的第一個(gè)列子里,檢索安裝的應(yīng)用列表并填充RecycleView的item來展示它們。我們也設(shè)想一個(gè)下拉privateprivateObservable<AppInfo>getApps(){returnObservable.create(subscriber->{List<AppInfoRich>apps=newfinalIntentmainIntent=newIntent(Intent.ACTION_MAIN,null);List<ResolveInfo>infos=getActivity().getPackageManager().queryIntentActivities(mainIntent,0);for(ResolveInfoinfo:infos){apps.add(new}for(AppInfoRichappInfo:apps)Bitmapicon=Utils.drawableToBitmap(appInfo.getIcon());Stringname=appInfo.getName();StringiconPath=mFilesDir+"/"+name;(subscriber.isUnsubscribed()){retu}subscriber.onNext(new} AppInfo對(duì)象如下@Accessors(prefix=publicclassAppInfoimplementsComparable<Object>StringmName;StringpublicAppInfo(StringnName,longlastUpdateTime,String{mName=nName;mIcon=icon;mLastUpdateTime=}publicpublicintcompareTo(Object{AppInfof=return}}此時(shí),我們可以訂閱Observable并觀察它。訂閱一個(gè)Observable意味著當(dāng)我們需要的數(shù)據(jù)進(jìn)來時(shí)須提供對(duì)當(dāng)前的場(chǎng)景是什么?我們展示一個(gè)進(jìn)度條來等待數(shù)據(jù)。當(dāng)數(shù)據(jù)到來時(shí),我們需要隱藏掉進(jìn)度條,填充list,最終展示列表?,F(xiàn)在,我們知道當(dāng)一切都準(zhǔn)備好了該做什么。那么錯(cuò)誤的場(chǎng)景呢?對(duì)于錯(cuò)誤這種情況,我們僅僅是用ast展示一個(gè)錯(cuò)誤的信息。使用ButterKnife,我們得到list和下拉刷新組件的RecyclerViewmRecycleView;SwipeRefreshLayoutmSwipeRefreshLayout;我們使用Android5的標(biāo)準(zhǔn)組件:RecyclerView和SwipeRefreshLayout。截屏展示了我們這個(gè)簡(jiǎn)單App的listFrag我們使用一個(gè)下拉刷新方法,因此列表數(shù)據(jù)可以來自初始化加載,或由用戶觸發(fā)的一個(gè)刷新動(dòng)作。針對(duì)這兩個(gè)場(chǎng)景,我們用同樣的行為,因此我們把我們的觀察者放在一個(gè)易被復(fù)用的函數(shù)里面。下面是我們的觀察者,定義了成功、失敗、完成要做的事情:privateprivatevoid{.subscribe(newObserver<List<AppInfo>>()publicpleted()Toast.makeText(getActivity(),"Hereisthelist!",}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",Toast.LENGTH_SHORT).show();}publicvoidonNext(List<AppInfo>}}定義一個(gè)函數(shù)使我們能夠用同樣一個(gè)block來處理兩種場(chǎng)景成為了可能。當(dāng)fragment加載時(shí)我們只需調(diào)用heList()方法并設(shè)置refreshTheList()方法作為用戶下拉這一行為所觸發(fā)的方我們第一個(gè)例子現(xiàn)在完成了,運(yùn)行跑一從列表創(chuàng)建一個(gè)在這個(gè)例子中,引入from()函數(shù)。使用這個(gè)特殊的“創(chuàng)建”函數(shù),我們可以從一個(gè)列表中創(chuàng)建一個(gè)Observ為了實(shí)現(xiàn)和第一個(gè)例子同樣的結(jié)果,我們?cè)诿恳粋€(gè)onNext()函數(shù)更新我們的適配器,添加元素并通知插復(fù)用和第一個(gè)例子同樣的結(jié)構(gòu)。主要的不同的是我們不再檢索已安裝的應(yīng)用列表。列表由外部實(shí)體提mAppsmApps=獲得列表后,我們僅需將它響應(yīng)化并填充RecyclerView的privatevoidprivatevoidloadList(List<AppInfo>.subscribe(newObserver<AppInfo>()public{Toast.makeText(getActivity(),"Hereisthelist!",}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",Toast.LENGTH_SHORT).show();}publicvoidonNext(AppInfo{mAddedApps.add(appInfo);mAdapter.addApplication(mAddedApps.size()-1,appInfo);}}正如你看到的,已安裝的應(yīng)用程序列表作為參數(shù)傳進(jìn)from()函數(shù),然后我們訂閱生成的Observable。觀察者和我們第一個(gè)例子中的觀察者十分相像。一個(gè)主要的不同是我們 pleted()函數(shù)中停掉進(jìn)度條是因?yàn)閭円粋€(gè)一個(gè)的發(fā)射元素;第一個(gè)例子中的Observable發(fā)射的是整個(gè)list,因此在onNext()函數(shù)中停掉進(jìn)度條的做,再多幾個(gè),))

,和timer()方法展示假如我們只有3個(gè)獨(dú)立的AppInfo對(duì)象并且我們想把他們轉(zhuǎn)化為Observable并填充到RecyclerView的item中ListList<AppInfo>apps=ApplicationsList.getInstance().getList();AppInfoappOne=apps.get(0);AppInfoappTwo=apps.get(10);AppInfoappThree=apps.get(24);我們可以像我們之前的例子那樣檢索列表并提取出這三個(gè)元素。然后他們傳到這個(gè)loadApps()函數(shù)里面privateprivatevoidloadApps(AppInfoappOne,AppInfoappTwo,AppInfo.subscribe(newObserver<AppInfo>()public{Toast.makeText(getActivity(),"Hereisthelist!",}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",Toast.LENGTH_SHORT).show();}publicvoidonNext(AppInfo{mAddedApps.add(appInfo);mAdapter.addApplication(mAddedApps.size()-1,appInfo);}}正如你看到的,代碼和之前的例子很像。這種方法讓我們有機(jī)會(huì)來考慮一下代碼的復(fù)你可以將一個(gè)函數(shù)作為參數(shù)傳給just()方法,你將會(huì)得到一個(gè)已存在代碼的原始Observable版本。在一個(gè)新的響假如你想對(duì)一個(gè)Observable重復(fù)發(fā)射三次數(shù)據(jù)。例如,我們用just()例子中的privateprivatevoidloadApps(AppInfoappOne,AppInfoappTwo,AppInfo.subscribe(newObserver<AppInfo>()public{Toast.makeText(getActivity(),"Hereisthelist!",}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",Toast.LENGTH_SHORT).show();}publicvoidonNext(AppInfo{mAddedApps.add(appInfo);mAdapter.addApplication(mAddedApps.size()-1,appInfo);}}正如你看到的,我們?cè)趈ust創(chuàng)建Observable后追加了repeat(3),它將會(huì)創(chuàng)建9個(gè)元素的序列,每一個(gè)都單獨(dú)有這樣一個(gè)場(chǎng)景,你想在這一個(gè)Observable但是你又想推遲這個(gè)Observable的創(chuàng)建直到觀察者訂閱時(shí)??聪旅娴膅etInt()函數(shù):privateprivateObservable<Integer>getInt(){returnObservable.create(subscriber-}}這比較簡(jiǎn)單,并且它沒有做太多事情,但是它正好為我們服務(wù)。現(xiàn)在,我們可以創(chuàng)建一個(gè)新的Observable用defer()ObservableObservable<Integer>deferred=這次,deferred存在,但是getInt()create()方法還沒有調(diào)用:logcat日志也沒有“GETINT”打印出來deferred.subscribe(numberdeferred.subscribe(number-{但是一旦我們訂閱了,create()方法就會(huì)被調(diào)用并且我們也可以在logcat日志中得到下賣弄兩個(gè):GETINT和42你需要從一個(gè)指定的數(shù)字X開始發(fā)射N個(gè)數(shù)字嗎?你可以用range.subscribe(newObserver<Integer>()publicpleted()Toast.makeText(getActivity(),"Yeaaah!",}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",}publicvoidonNext(Integernumber)Toast.makeText(getActivity(),"Isay"+number,}range()函數(shù)用兩個(gè)數(shù)字作為參數(shù):第一個(gè)是起始點(diǎn),第二個(gè)是我們想發(fā)射數(shù)字的個(gè)interval()函數(shù)在你需要?jiǎng)?chuàng)建一個(gè)輪詢程序時(shí)非常好SubscriptionSubscriptionstopMePlease=.subscribe(newObserver<Integer>()publicpleted()Toast.makeText(getActivity(),"Yeaaah!",}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",}publicvoidpublicvoidonNext(Integernumber)Toast.makeText(getActivity(),"Isay"+number,}interval()函數(shù)的兩個(gè)參數(shù):一個(gè)指定兩次發(fā)射的時(shí)間間隔,另一個(gè)是用到的時(shí)間單如果你需要一個(gè)一段時(shí)間之后才發(fā)射的Observable,你可以像下面的例子使用timer().subscribe(newObserver<Long>()publicpleted()}publicvoidonError(Throwablee)}publicvoidonNext(Long{Log.d("RXJAVA","Isay"+}它將3秒后發(fā)射0,然后就完成了。讓我們使用timer()的第三個(gè)參數(shù),就像下面的例.subscribe(newObserver<Long>()publicpleted()}publicvoidonError(Throwablee)}publicvoidonNext(Long{Log.d("RXJAVA","Isay"+}用這個(gè)代碼,你可以創(chuàng)建一個(gè)以初始值來延遲(上一個(gè)例子是3秒)執(zhí)行的interval()版本,然后每隔N秒就發(fā)射總在下一章中,掌握過濾操作,能夠從我們接收到的序列中創(chuàng)建我們需要的序列55這一章中,研究可觀列的本質(zhì):過濾。學(xué)到如何從發(fā)射的Observable中選取我們想要的值,如 過濾RxJava讓我們使用filter()方法來過濾我們觀列中不想要的值,在上一章中,我們?cè)趲讉€(gè)例子中使用了已安裝的應(yīng)用列表,但是我們只想展示以字母C開頭的已安裝的應(yīng)用該怎么辦呢?在這個(gè)新的例子中,使用同樣的列表,但是我們會(huì)過濾它,通過把合適的謂詞傳給filter()函數(shù)來得到我們想要的值。上一章中l(wèi)oadList()函數(shù)可以改成這樣privatevoidprivatevoidloadList(List<AppInfo>.filter((appInfo)->.subscribe(newObserver<AppInfo>()public{}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",Toast.LENGTH_SHORT).show();}publicvoidonNext(AppInfo{mAddedApps.add(appInfo);mAdapter.addApplication(mAddedApps.size()-1,appInfo);}}我們從上一章中的loadList()函數(shù)中添加下面一行.fliter((appInfo.fliter((appInfo->Func1<AppInfo,Boolean>(){@OverridepublicBooleancall(AppInfoappInfo){return}我們傳一個(gè)新的Func1對(duì)象給filter()函數(shù),即只有一個(gè)參數(shù)的函數(shù)。Func1有一個(gè)AppInfo對(duì)象來作為它參數(shù)類型并且返回Boolean對(duì)象。只要條件符合filter()函數(shù)就會(huì)返回true。此時(shí),值會(huì)發(fā)射出去并且所有的正如你想的那樣,從一個(gè)我們得到的可觀列中創(chuàng)建一個(gè)我們需要的序列filter()是很好用的。我們不需要知道可觀列的源或者為什么發(fā)射這么多不同的數(shù)據(jù)。我們只是想要這些元素的子集來創(chuàng)建一個(gè)可以在應(yīng)用中使filter()函數(shù)最常用的用法之一時(shí)過濾null對(duì)象publicBooleancall(AppInfoappInfo){returnappInfo!=}這看起來簡(jiǎn)單,對(duì)于簡(jiǎn)單的事情有許多模板代碼,但是它幫我們免去了在onNext()函數(shù)調(diào)用中再去檢測(cè)值,讓我們把注意力集中在應(yīng)用業(yè)務(wù)邏輯下圖展示了過濾出的C字母開頭的已安裝的應(yīng)用列獲取我們需要的當(dāng)我們不需要整個(gè)序列時(shí),而是只想取開頭或結(jié)尾的幾個(gè)元素,我們可以用take()或takeLast()如果我們只想要一個(gè)可觀列中的前三個(gè)元素那將會(huì)怎么樣,發(fā)射它們,然后讓Observable完成嗎?take()函privatevoidprivatevoidloadList(List<AppInfo>.subscribe(newObserver<AppInfo>()public{}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",Toast.LENGTH_SHORT).show();}publicvoidonNext(AppInfo{mAddedApps.add(appInfo);mAdapter.addApplication(mAddedApps.size()-1,appInfo);}}下圖中展示了發(fā)射數(shù)字的一個(gè)可觀列。我們對(duì)這個(gè)可觀列應(yīng)用take(2)函數(shù),然后我們創(chuàng)建一個(gè)只發(fā)射如果我們想要最后N個(gè)元素,我們只需使用takeLast()函數(shù)下圖中展示了如何從可觀測(cè)源中發(fā)射最后一個(gè)元素來創(chuàng)建一個(gè)新的序下圖中展示了我們?cè)谝寻惭b的應(yīng)用列表使用take()和takeLast()函數(shù)后發(fā)生的結(jié)果有且僅有一一個(gè)可觀列會(huì)在出錯(cuò)時(shí)重復(fù)發(fā)射或者被設(shè)計(jì)成重復(fù)發(fā)射。distinct()和distinctUntilChanged()函數(shù)可以方如果我們想對(duì)一個(gè)指定的值僅處理一次該怎么辦?我們可以對(duì)我們的序列使用distinct()函數(shù)去掉重復(fù)的。就takeLast()一樣,distinct()作用于一個(gè)完整的序列,然后得到重復(fù)的過濾項(xiàng),它需要記錄每一個(gè)發(fā)射的下圖展示了如何在一個(gè)發(fā)射1和2兩次的可觀測(cè)源上創(chuàng)建一個(gè)無重的序?yàn)榱藙?chuàng)建我們例子中序列,使用我們至今已經(jīng)學(xué)到的幾個(gè)方法:*take():它有一小組的可識(shí)別的數(shù)據(jù)項(xiàng)。*repeat():創(chuàng)建一個(gè)有重復(fù)的大的序列。然后,應(yīng)用distinct()函數(shù)來去除重復(fù)ObservableObservable<AppInfo>fullOfDuplicates=fullOfDuplicates變量里把我們已安裝應(yīng)用的前三個(gè)重復(fù)了3次:有9個(gè)并且許多重復(fù)的。然后,我們使用ct().subscribe(newObserver<AppInfo>()public{}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",Toast.LENGTH_SHORT).show();}publicvoidonNext(AppInfo{mAddedApps.add(appInfo);mAdapter.addApplication(mAddedApps.size()-1,appInfo);}}結(jié)果,很明顯,我們得如果在一個(gè)可觀列發(fā)射一個(gè)不同于之前的一個(gè)新值時(shí)讓我們得到通知這時(shí)候該怎么做?我們猜想一下我們觀數(shù)據(jù)。我們想忽略掉重復(fù)的值并且在溫度確實(shí)改變時(shí)才想得到通知。ditinctUntilChanged()過濾函數(shù)能做到這一下圖用圖形化的方式展示了我們?nèi)绾螌istinctUntilChanged()函數(shù)應(yīng)用在一個(gè)存在的序列上來創(chuàng)建一個(gè)新的不Firstand下圖展示了如何從一個(gè)從可觀測(cè)源序列中創(chuàng)建只發(fā)射第一個(gè)元素的序first()方法和last()方法很容易弄明白。它們從Observable中只發(fā)射第一個(gè)元素或者最后一個(gè)元素。這兩個(gè)可以傳Func1作為參數(shù),:一個(gè)可以確定我們感的第一個(gè)或者最后一個(gè)的謂詞下圖展示了last()應(yīng)用在一個(gè)完成的序列上來創(chuàng)建一個(gè)僅僅發(fā)射最后一個(gè)元素的新的Observable與first()和last()相似的變量有:firstOrDefault()和lastOrDefault().這兩個(gè)函數(shù)當(dāng)可觀列完成時(shí)不Skipand下圖中展示了如何使用skip(2)來創(chuàng)建一個(gè)不發(fā)射前兩個(gè)元素而是發(fā)射它后面的那些數(shù)據(jù)的序skip()和skipLast()函數(shù)與take()和takeLast()相對(duì)應(yīng)。它們用整數(shù)N作參數(shù),從本質(zhì)上來說,它們不讓ervable發(fā)射前N個(gè)或者后N個(gè)值。如果我們知道一個(gè)序列以沒有太多用的“可控”元素開頭或結(jié)尾時(shí)我們可以使用它。下圖與前一個(gè)場(chǎng)景相對(duì)應(yīng):我們創(chuàng)建一個(gè)新的序列,它會(huì)跳過后面兩個(gè)元素從源序列中發(fā)射剩下的其他元如果我們只想要可觀列發(fā)射的第五個(gè)元素該怎么辦?elementAt()函數(shù)僅從一個(gè)序列中發(fā)射第n個(gè)元素然后就如果我們想查找第五個(gè)元素但是可觀列只有三個(gè)元素可供發(fā)射時(shí)該怎么辦?我們可以使用elementAtOrDefault()。下圖展示了如何通過使用elementAt(2)從一個(gè)序列中選擇第三個(gè)元素以及如何創(chuàng)建一個(gè)只發(fā)射指定元素的們可以使用一個(gè)小的發(fā)射間隔。在Observable后面加一個(gè)sample(),創(chuàng)建一個(gè)新的可觀列,它將在一ObservableObservable<Integer>sensor=.subscribe(newObserver<Integer>()publicpleted()}publicvoidonError(Throwablee)}publicvoidonNext(Integer{}例子中Observable將會(huì)觀測(cè)溫度Observable然后每隔30秒就會(huì)發(fā)射最后一個(gè)溫度值。很明顯,sample()支持全部如果我們想讓它定時(shí)發(fā)射第一個(gè)元素而不是最近的一個(gè)元素,我們可以使用throttleFirst()一個(gè),我們可以使用timeout()函數(shù)來源可觀列,就是在我們?cè)O(shè)定的時(shí)間間隔內(nèi)如果沒有得到一個(gè)值則發(fā)射一個(gè)錯(cuò)誤。我們可以認(rèn)為timeout()為一個(gè)Observable的限時(shí)的副本。如果在指定的時(shí)間間隔內(nèi)Observable不發(fā)射值的話,它的原始的Observable時(shí)就會(huì)觸發(fā)onError()函數(shù)SubscriptionsubscriptionSubscriptionsubscription=.subscribe(newObserver<Integer>()publicpleted()}publicvoidonError(Throwablee)Log.d("RXJAVA","Youshouldgocheckthesensor,}publicvoidonNext(Integer{}和sample()一樣,timeout()使用TimeUnit對(duì)象來指定時(shí)間間隔下圖中展示了一旦Observable超過了限時(shí)就會(huì)觸發(fā)onError()函數(shù):因?yàn)槌瑫r(shí)后它才到達(dá),所以最后一個(gè)元素將debounce()函數(shù)過濾掉由Observable發(fā)射的速率過快的數(shù)據(jù);如果在一個(gè)指定的時(shí)間間隔過去了仍舊沒有發(fā)射一就像sample()和timeout()函數(shù)一樣,debounce()使用TimeUnit對(duì)象指定時(shí)間間隔下圖展示了多久從Observable發(fā)射一次新的數(shù)據(jù),debounce()函數(shù)開啟一個(gè)內(nèi)部定時(shí)器,如果在這個(gè)時(shí)間間隔內(nèi)總這一章中,我們學(xué)習(xí)了如何過濾一個(gè)可觀列。我們現(xiàn)在可以使用filter(),skip(),和sample()來創(chuàng)建我下一章中,學(xué)習(xí)如何轉(zhuǎn)換一個(gè)序列,將函數(shù)應(yīng)用到每個(gè)元素,給它們分組和掃描來創(chuàng)建我們所需要的能完66在上一章中,我們探索了RxJava通用過濾方法。我們學(xué)習(xí)了如何使用filter()方法過濾我們不需要的值,如何用take()得到發(fā)射元素的子集,如何使用distinct()函數(shù)來去除重復(fù)的。我們學(xué)習(xí)了如何借助timeout(),mple(),以及debounce()來利用時(shí)間這一章中 通過學(xué)習(xí)如何變換可 列來創(chuàng)建一個(gè)能夠更好的滿足我們需求的序列,flatMap(),RxJava提供了幾個(gè) 函數(shù),flatMap(),這些函數(shù)都作用于一個(gè)可觀列,然后變換它發(fā)射的值,最后用一種新的形式返回它們。讓我們用合適的“真RxJava的map函數(shù)接收一個(gè)指定的Func對(duì)象然后將它應(yīng)用到每一個(gè)由Observable發(fā)射的值上。下圖展示了如何考慮下我們已安裝的應(yīng)用列表。我們?cè)趺床拍軌蝻@示同樣的列表,但是又要所有的名字都小寫呢我們的loadList()函數(shù)可以改成這樣privatevoidprivatevoidloadList(List<AppInfo>Func1<AppInfo,AppInfo>(){@OverrpublicAppinfocall(AppInfoappInfo){StringcurrentName=StringlowerCaseName=currentName.toLowerCase();return}.subscribe(newObserver<AppInfo>()}}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",Toast.LENGTH_SHORT).show();}publicvoidonNext(AppInfo{mAddedApps.add(appInfo);mAdapter.addApplication(mAddedApps.size()-1,appInfo);}}正如你看到的,像往常一樣創(chuàng)建我們發(fā)射的Observable之后,我們追加一個(gè)map調(diào)用,我們創(chuàng)建一個(gè)簡(jiǎn)單的函來更新AppInfo對(duì)象并提供一個(gè)名字小寫的新版本給觀察者在復(fù)雜的場(chǎng)景中,我們有一個(gè)這樣的Observable:它發(fā)射一個(gè)數(shù)據(jù)序列,這些數(shù)據(jù)本身也可以發(fā)射Observable。xJava的flatMap()函數(shù)提供一種鋪平序列的方式,然后合并這些Observables發(fā)射的數(shù)據(jù),最后將合并后的結(jié)果當(dāng)我們?cè)谔幚砜赡苡写罅康腛bservables時(shí),重要是記住任何一個(gè)Observables發(fā)生錯(cuò)誤的情況,flatMap()將觸發(fā)它自己的onError()函數(shù)并放棄整個(gè)鏈重要的一點(diǎn)提示是關(guān)于合并部分:它允許交叉。正如上圖所示,這意味著flatMap()不能夠保證在最終生成的ObsRxJava的concatMap()函數(shù)解決了flatMap()的交叉問題,提供了一種能夠把發(fā)射的值連續(xù)在一起的鋪平函作為*map的一員,flatMapInterable()和flatMap()很像。僅有的本質(zhì)不同是它將源數(shù)據(jù)兩兩結(jié)成對(duì)并生成ISwit如下圖所示 和flatMap()很像,除了一點(diǎn):每當(dāng)源Observable發(fā)射一個(gè)新的數(shù)據(jù)項(xiàng)(Observable)時(shí),它將取消訂閱并停止監(jiān)視之前那個(gè)數(shù)據(jù)項(xiàng)產(chǎn)生的ObservableRxJava的scan函數(shù)可以看做是一個(gè)累積函數(shù)。scan()函數(shù)對(duì)原始Observable發(fā)射的每一項(xiàng)數(shù)據(jù)都應(yīng)用一個(gè)函作為一個(gè)通用的例子,給出一個(gè)累加.scan((sum,item)->sum+.subscribe(new{publicvoid pleted(){Log.d("RXJAVA","Sequencecompleted.");}publicvoidonError(Throwable{Log.e("RXJAVA","Somethingwent}publicvoidonNext(Integer{Log.d("RXJAVA","itemis:"+}我們得到的結(jié)果是RXJAVARXJAVA:itemis:1RXJAVA:itemis:3RXJAVA:itemis:6RXJAVA:itemis:10RXJAVA:itemis:RXJAVA:Sequence我們也可以創(chuàng)建一個(gè)新版本的loadList()函數(shù)用來比較每個(gè)安裝應(yīng)用的名字從而創(chuàng)建一個(gè)名字長(zhǎng)度遞增的列privatevoidprivatevoidloadList(List<AppInfo>.scan((appInfo,appInfo2)->{appInfo2.getName().length()){return}elsereturn}.subscribe(newObserver<AppInfo>()public{}publicvoidpublicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",Toast.LENGTH_SHORT).show();}publicvoidonNext(AppInfo{mAddedApps.add(appInfo);mAdapter.addApplication(mAddedApps.size()-1,appInfo);}}結(jié)果如下有一個(gè)scan()函數(shù)的變體,它用初始值作為第一個(gè)發(fā)射的值,方法簽名看起來像:scan(R,Func2),如下圖中的拿第一個(gè)例子開始,我們安裝的應(yīng)用程序列表按照字母表的順序排序。然而,如果現(xiàn)在我們想按照最近更新日來排序我們的App時(shí)該怎么辦?RxJava提供了一個(gè)有用的函數(shù)從列表中按照指定的規(guī)則:groupBy()來分素。下圖中的例子展示了groupBy()如何將發(fā)射的值根據(jù)他們的形狀來進(jìn)行分這個(gè)函數(shù)將源Observable變換成一個(gè)發(fā)射Observables的新的Observable。它們中的每一個(gè)新的Observable一組指定的數(shù)據(jù)。為了創(chuàng)建一個(gè)分組了的已安裝應(yīng)用列表,我們?cè)趌oadList()函數(shù)中引入了一個(gè)新的元ObservableObservable<GroupedObservable<String,AppInfo>>groupedItems=Func1<AppInfo,String>(){@OverridepublicStringcall(AppInfoappInfo){SimpleDateFormatformatter=newSimpleDateFormat("MM/yyyy");returnformatter.format(newDate(appInfo.getLastUpdateTime()));}現(xiàn)在我們創(chuàng)建了一個(gè)新的Observable,groupedItems,它將會(huì)發(fā)射一個(gè)帶有GroupedObservable的序列。dObservable是一個(gè)特殊的Observable,它源自一個(gè)分組的key。在這個(gè)例子中,key就是String,代表的意思Month/Year格式化的最近更新日期這一點(diǎn),我們已經(jīng)創(chuàng)建了幾個(gè)發(fā)射AppInfo數(shù)據(jù)的Observable,用來填充我們的列表。我們想保留字母排序和分組排序。創(chuàng)建一個(gè)新的Observable將所有的聯(lián)系起來,像往常一樣然后訂閱它:.subscribe(newObserver<AppInfo>()public{}publicvoidonError(Throwablee)Toast.makeText(getActivity(),"Somethingwentwrong!",Toast.LENGTH_SHORT).show();}publicvoidonNext(AppInfo{mAddedApps.add(appInfo);mAdapter.addApplication(mAddedApps.size()-1,appInfo);}我們的loadList()函數(shù)完成了,結(jié)果是RxJava中的buffer()函數(shù)將源Observable變換一個(gè)新的Observable,這個(gè)新的Observable每次發(fā)射一組列表值而上圖中展示了buffer()如何將count作為一個(gè)參數(shù)來指定有多少數(shù)據(jù)項(xiàng)被包在發(fā)射的列表中。實(shí)際上,r()函數(shù)有幾種變體。其中有一個(gè)是允許你指定一個(gè)skip值:此后每skip項(xiàng)數(shù)據(jù),然后又用count項(xiàng)數(shù)據(jù)填充緩buffer()帶一個(gè)timespan的參數(shù),會(huì)創(chuàng)建一個(gè)每隔timespan時(shí)間段就會(huì)發(fā)射一個(gè)列表的ObservableRxJava的window()函數(shù)和buffer()很像,但是它發(fā)射的是Observable而不是列表。下圖展示了window()如何緩這些Observables中的每一個(gè)都發(fā)射原始Observable數(shù)據(jù)的一個(gè)子集,數(shù)量由count指定最后發(fā)射一 ed()結(jié)束。正如buffer()一樣,window也有一個(gè)skip變體,如下圖所示RxJava的cast()函數(shù)是本章中最后一個(gè)操作符。它是map()操作符的特殊版本。它將源Observable中的每一項(xiàng)據(jù)都轉(zhuǎn)換為新的類型,把它變成了不同的Class總這一章中,我們學(xué)習(xí)了RxJava時(shí)如何控制和轉(zhuǎn)換可觀列。用我們現(xiàn)在所學(xué)的知識(shí),我們可以創(chuàng)建、過濾、轉(zhuǎn)換我們所想要的任何種類的可觀列。下一章 學(xué)習(xí)如何組合Observable,合并它們,連接它們,再或者打包它們77上一章中,我們學(xué)到如何轉(zhuǎn)換可 列。我們也看到 ,以 有用的函數(shù)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論