Android:RxJava 結(jié)合 Retrofit 優(yōu)雅實(shí)現(xiàn) 網(wǎng)絡(luò)請求輪詢

姓名:白國樂

學(xué)號:17021210898

專業(yè):信號與信息處理

轉(zhuǎn)載自:http://blog.csdn.net/carson_ho/article/details/78558790,有刪節(jié)

【嵌牛導(dǎo)讀】Rxjava,由于其基于事件流的鏈?zhǔn)秸{(diào)用、邏輯簡潔 & 使用簡單的特點(diǎn),深受各大Android開發(fā)者的歡迎。

【嵌牛鼻子】Rxjava、實(shí)現(xiàn)

【嵌牛提問】如何實(shí)現(xiàn)RxJava ?

【嵌牛正文】目錄

1. 需求場景

注:關(guān)于Rxjava中的repeatWhen()操作符的使用請看文章Android RxJava:功能性操作符 全面講解

2. 功能說明

采用Get方法對 金山詞霸API 按規(guī)定時(shí)間重復(fù)發(fā)送網(wǎng)絡(luò)請求,從而模擬 輪詢 需求實(shí)現(xiàn)

停止輪詢的條件 = 當(dāng)輪詢到第4次時(shí)

采用Gson進(jìn)行數(shù)據(jù)解析

3. 具體實(shí)現(xiàn)

下面,我將結(jié)合 `Retrofit` 與`RxJava` 實(shí)現(xiàn) 有條件的輪詢需求

3.1 步驟說明

添加依賴

創(chuàng)建 接收服務(wù)器返回?cái)?shù)據(jù) 的類

創(chuàng)建 用于描述網(wǎng)絡(luò)請求 的接口(區(qū)別于Retrofit傳統(tǒng)形式)

創(chuàng)建 Retrofit 實(shí)例

創(chuàng)建 網(wǎng)絡(luò)請求接口實(shí)例 并 配置網(wǎng)絡(luò)請求參數(shù)(區(qū)別于Retrofit傳統(tǒng)形式)

發(fā)送網(wǎng)絡(luò)請求(區(qū)別于Retrofit傳統(tǒng)形式)

發(fā)送網(wǎng)絡(luò)請求

對返回的數(shù)據(jù)進(jìn)行處理

本實(shí)例側(cè)重于說明RxJava的輪詢需求,關(guān)于Retrofit的使用請看文章:這是一份很詳細(xì)的 Retrofit 2.0 使用教程(含實(shí)例講解)

3.2 步驟實(shí)現(xiàn)

步驟1: 添加依賴

a. 在 `Gradle`加入`Retrofit`庫的依賴*build.gradle*

dependencies {// Android 支持 Rxjava// 此處一定要注意使用RxJava2的版本compile'io.reactivex.rxjava2:rxjava:2.0.1'compile'io.reactivex.rxjava2:rxandroid:2.0.1'// Android 支持 Retrofitcompile'com.squareup.retrofit2:retrofit:2.1.0'// 銜接 Retrofit & RxJava// 此處一定要注意使用RxJava2的版本compile'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'// 支持Gson解析compile'com.squareup.retrofit2:converter-gson:2.1.0'}

b. 添加 網(wǎng)絡(luò)權(quán)限*AndroidManifest.xml*

1

步驟2:創(chuàng)建 接收服務(wù)器返回?cái)?shù)據(jù) 的類

金山詞霸API的數(shù)據(jù)格式說明如下:

//URL模板http://fy.iciba.com/ajax.php// URL實(shí)例http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=hello%20world// 參數(shù)說明:// a:固定值 fy// f:原文內(nèi)容類型,日語取 ja,中文取 zh,英語取 en,韓語取 ko,德語取 de,西班牙語取 es,法語取 fr,自動則取 auto// t:譯文內(nèi)容類型,日語取 ja,中文取 zh,英語取 en,韓語取 ko,德語取 de,西班牙語取 es,法語取 fr,自動則取 auto// w:查詢內(nèi)容

示例

根據(jù) 金山詞霸API 的數(shù)據(jù)格式,創(chuàng)建 接收服務(wù)器返回?cái)?shù)據(jù) 的類:

Translation.java

publicclassTranslation {privateintstatus;privatecontent content;privatestaticclasscontent {privateStringfrom;privateString to;privateString vendor;privateStringout;privateinterrNo;? ? }//定義 輸出返回?cái)?shù)據(jù) 的方法publicvoidshow() {? ? ? ? Log.d("RxJava", content.out);? ? }}

步驟3:創(chuàng)建 用于描述網(wǎng)絡(luò)請求 的接口

采用注解+Observable<...>接口描述 網(wǎng)絡(luò)請求參數(shù)

GetRequest_Interface.java

publicinterfaceGetRequest_Interface {? ? @GET("ajax.php?a=fy&f=auto&t=auto&w=hi%20world")? ? Observable getCall();// 注解里傳入 網(wǎng)絡(luò)請求 的部分URL地址// Retrofit把網(wǎng)絡(luò)請求的URL分成了兩部分:一部分放在Retrofit對象里,另一部分放在網(wǎng)絡(luò)請求接口里// 如果接口里的url是一個完整的網(wǎng)址,那么放在Retrofit對象里的URL可以忽略// 采用Observable<...>接口// getCall()是接受網(wǎng)絡(luò)請求數(shù)據(jù)的方法}

接下來的步驟均在RxJavafixRxjava.java內(nèi)實(shí)現(xiàn)(請看注釋)

RxJavafixRxjava.java

publicclassRxJavafixRetrofitextendsAppCompatActivity{privatestaticfinalString TAG ="Rxjava";// 設(shè)置變量 = 模擬輪詢服務(wù)器次數(shù)privateinti =0;@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_main);// 步驟1:創(chuàng)建Retrofit對象Retrofit retrofit =newRetrofit.Builder()? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .baseUrl("http://fy.iciba.com/")// 設(shè)置 網(wǎng)絡(luò)請求 Url.addConverterFactory(GsonConverterFactory.create())//設(shè)置使用Gson解析(記得加入依賴).addCallAdapterFactory(RxJava2CallAdapterFactory.create())// 支持RxJava.build();// 步驟2:創(chuàng)建 網(wǎng)絡(luò)請求接口 的實(shí)例GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);// 步驟3:采用Observable<...>形式 對 網(wǎng)絡(luò)請求 進(jìn)行封裝Observable observable = request.getCall();// 步驟4:發(fā)送網(wǎng)絡(luò)請求 & 通過repeatWhen()進(jìn)行輪詢observable.repeatWhen(newFunction, ObservableSource>() {@Override// 在Function函數(shù)中,必須對輸入的 Observable進(jìn)行處理,此處使用flatMap操作符接收上游的數(shù)據(jù)publicObservableSourceapply(@NonNull Observable objectObservable)throwsException {// 將原始 Observable 停止發(fā)送事件的標(biāo)識(Complete() /? Error())轉(zhuǎn)換成1個 Object 類型數(shù)據(jù)傳遞給1個新被觀察者(Observable)// 以此決定是否重新訂閱 & 發(fā)送原來的 Observable,即輪詢// 此處有2種情況:// 1. 若返回1個Complete() /? Error()事件,則不重新訂閱 & 發(fā)送原來的 Observable,即輪詢結(jié)束// 2. 若返回其余事件,則重新訂閱 & 發(fā)送原來的 Observable,即繼續(xù)輪詢r(jià)eturnobjectObservable.flatMap(newFunction>() {@OverridepublicObservableSourceapply(@NonNull Object throwable)throwsException {// 加入判斷條件:當(dāng)輪詢次數(shù) = 5次后,就停止輪詢if(i >3) {// 此處選擇發(fā)送onError事件以結(jié)束輪詢,因?yàn)榭捎|發(fā)下游觀察者的onError()方法回調(diào)returnObservable.error(newThrowable("輪詢結(jié)束"));? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }// 若輪詢次數(shù)<4次,則發(fā)送1Next事件以繼續(xù)輪詢// 注:此處加入了delay操作符,作用 = 延遲一段時(shí)間發(fā)送(此處設(shè)置 = 2s),以實(shí)現(xiàn)輪詢間間隔設(shè)置returnObservable.just(1).delay(2000, TimeUnit.MILLISECONDS);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });? ? ? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? }).subscribeOn(Schedulers.io())// 切換到IO線程進(jìn)行網(wǎng)絡(luò)請求.observeOn(AndroidSchedulers.mainThread())// 切換回到主線程 處理請求結(jié)果.subscribe(newObserver() {@OverridepublicvoidonSubscribe(Disposable d) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }@OverridepublicvoidonNext(Translation result) {// e.接收服務(wù)器返回的數(shù)據(jù)result.show() ;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? i++;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }@OverridepublicvoidonError(Throwable e) {// 獲取輪詢結(jié)束信息Log.d(TAG,? e.toString());? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }@OverridepublicvoidonComplete() {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });? ? ? ? ? ? ? ? ? ? }? ? }

3.3? 測試結(jié)果

4. Demo地址

Carson_Ho的Github地址 = RxJava2實(shí)戰(zhàn)系列:有條件的輪詢

關(guān)于無條件的網(wǎng)絡(luò)請求輪詢,具體請看文章Android RxJava 實(shí)際應(yīng)用講解:網(wǎng)絡(luò)請求輪詢

5. 總結(jié)

本文主要講解了Rxjava創(chuàng)建操作符的實(shí)際開發(fā)需求場景:有條件輪詢需求,并結(jié)合Retrofit與RxJava實(shí)現(xiàn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,570評論 2 379

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