姓名:白國樂
學(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 ?
【嵌牛正文】目錄
注:關(guān)于Rxjava中的repeatWhen()操作符的使用請看文章Android RxJava:功能性操作符 全面講解
采用Get方法對 金山詞霸API 按規(guī)定時(shí)間重復(fù)發(fā)送網(wǎng)絡(luò)請求,從而模擬 輪詢 需求實(shí)現(xiàn)
停止輪詢的條件 = 當(dāng)輪詢到第4次時(shí)
采用Gson進(jìn)行數(shù)據(jù)解析
下面,我將結(jié)合 `Retrofit` 與`RxJava` 實(shí)現(xiàn) 有條件的輪詢需求
添加依賴
創(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í)例講解)
步驟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() {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });? ? ? ? ? ? ? ? ? ? }? ? }
Carson_Ho的Github地址 = RxJava2實(shí)戰(zhàn)系列:有條件的輪詢
關(guān)于無條件的網(wǎng)絡(luò)請求輪詢,具體請看文章Android RxJava 實(shí)際應(yīng)用講解:網(wǎng)絡(luò)請求輪詢
本文主要講解了Rxjava創(chuàng)建操作符的實(shí)際開發(fā)需求場景:有條件輪詢需求,并結(jié)合Retrofit與RxJava實(shí)現(xiàn)