Android:RxJava 結合 Retrofit 優雅實現 網路請求輪詢
阿新 • • 發佈:2019-01-04
前言
Rxjava
,由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大Android
開發者的歡迎。
RxJava
如此受歡迎的原因,在於其提供了豐富 & 功能強大的操作符,幾乎能完成所有的功能需求- 今天,我將為大家帶來
Rxjava
建立操作符的實際開發需求場景:有條件的輪詢需求 ,並結合Retrofit
與RxJava
實現,希望大家會喜歡。
- 本系列文章主要基於
Rxjava 2.0
- 接下來的時間,我將持續推出
Android
中Rxjava 2.0
的一系列文章,包括原理、操作符、應用場景、背壓等等 ,有興趣可以繼續關注Carson_Ho的安卓開發筆記!!
目錄
1. 需求場景
2. 功能說明
採用Get
方法對 金山詞霸API 按規定時間重複傳送網路請求,從而模擬 輪詢 需求實現
- 停止輪詢的條件 = 當輪詢到第4次時
- 採用
Gson
進行資料解析
3. 具體實現
下面,我將結合 `Retrofit` 與`RxJava` 實現 有條件的輪詢需求3.1 步驟說明
- 新增依賴
- 建立 接收伺服器返回資料 的類
- 建立 用於描述網路請求 的介面(區別於
Retrofit
傳統形式) - 建立 Retrofit 例項
- 建立 網路請求介面例項 並 配置網路請求引數(區別於
Retrofit
- 傳送網路請求(區別於
Retrofit
傳統形式) - 傳送網路請求
- 對返回的資料進行處理
3.2 步驟實現
步驟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 支援 Retrofit
compile '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. 新增 網路許可權
*AndroidManifest.xml*
<uses-permission android:name="android.permission.INTERNET"/>
步驟2:建立 接收伺服器返回資料 的類
- 金山詞霸
API
的資料格式說明如下:
// URL模板
http://fy.iciba.com/ajax.php
// URL例項
http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=hello%20world
// 引數說明:
// a:固定值 fy
// f:原文內容型別,日語取 ja,中文取 zh,英語取 en,韓語取 ko,德語取 de,西班牙語取 es,法語取 fr,自動則取 auto
// t:譯文內容型別,日語取 ja,中文取 zh,英語取 en,韓語取 ko,德語取 de,西班牙語取 es,法語取 fr,自動則取 auto
// w:查詢內容
- 示例
- 根據 金山詞霸API 的資料格式,建立 接收伺服器返回資料 的類:
Translation.java
public class Translation {
private int status;
private content content;
private static class content {
private String from;
private String to;
private String vendor;
private String out;
private int errNo;
}
//定義 輸出返回資料 的方法
public void show() {
Log.d("RxJava", content.out );
}
}
步驟3:建立 用於描述網路請求 的介面
採用 註解 + Observable<...>
介面描述 網路請求引數
GetRequest_Interface.java
public interface GetRequest_Interface {
@GET("ajax.php?a=fy&f=auto&t=auto&w=hi%20world")
Observable<Translation> getCall();
// 註解裡傳入 網路請求 的部分URL地址
// Retrofit把網路請求的URL分成了兩部分:一部分放在Retrofit物件裡,另一部分放在網路請求接口裡
// 如果接口裡的url是一個完整的網址,那麼放在Retrofit物件裡的URL可以忽略
// 採用Observable<...>介面
// getCall()是接受網路請求資料的方法
}
接下來的步驟均在RxJavafixRxjava.java內實現(請看註釋)
RxJavafixRxjava.java
public class RxJavafixRetrofit extends AppCompatActivity {
private static final String TAG = "Rxjava";
// 設定變數 = 模擬輪詢伺服器次數
private int i = 0 ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 步驟1:建立Retrofit物件
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://fy.iciba.com/") // 設定 網路請求 Url
.addConverterFactory(GsonConverterFactory.create()) //設定使用Gson解析(記得加入依賴)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支援RxJava
.build();
// 步驟2:建立 網路請求介面 的例項
GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
// 步驟3:採用Observable<...>形式 對 網路請求 進行封裝
Observable<Translation> observable = request.getCall();
// 步驟4:傳送網路請求 & 通過repeatWhen()進行輪詢
observable.repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() {
@Override
// 在Function函式中,必須對輸入的 Observable<Object>進行處理,此處使用flatMap操作符接收上游的資料
public ObservableSource<?> apply(@NonNull Observable<Object> objectObservable) throws Exception {
// 將原始 Observable 停止傳送事件的標識(Complete() / Error())轉換成1個 Object 型別資料傳遞給1個新被觀察者(Observable)
// 以此決定是否重新訂閱 & 傳送原來的 Observable,即輪詢
// 此處有2種情況:
// 1. 若返回1個Complete() / Error()事件,則不重新訂閱 & 傳送原來的 Observable,即輪詢結束
// 2. 若返回其餘事件,則重新訂閱 & 傳送原來的 Observable,即繼續輪詢
return objectObservable.flatMap(new Function<Object, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(@NonNull Object throwable) throws Exception {
// 加入判斷條件:當輪詢次數 = 5次後,就停止輪詢
if (i > 3) {
// 此處選擇傳送onError事件以結束輪詢,因為可觸發下游觀察者的onError()方法回撥
return Observable.error(new Throwable("輪詢結束"));
}
// 若輪詢次數<4次,則傳送1Next事件以繼續輪詢
// 注:此處加入了delay操作符,作用 = 延遲一段時間傳送(此處設定 = 2s),以實現輪詢間間隔設定
return Observable.just(1).delay(2000, TimeUnit.MILLISECONDS);
}
});
}
}).subscribeOn(Schedulers.io()) // 切換到IO執行緒進行網路請求
.observeOn(AndroidSchedulers.mainThread()) // 切換回到主執行緒 處理請求結果
.subscribe(new Observer<Translation>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Translation result) {
// e.接收伺服器返回的資料
result.show() ;
i++;
}
@Override
public void onError(Throwable e) {
// 獲取輪詢結束資訊
Log.d(TAG, e.toString());
}
@Override
public void onComplete() {
}
});
}
}
3.3 測試結果
4. Demo地址
5. 總結
- 本文主要講解了
Rxjava
建立操作符的實際開發需求場景:有條件輪詢需求 ,並結合Retrofit
與RxJava
實現 - 下面我將結合 實際場景應用 &
Rxjava
的相關使用框架(如Retrofit
、Eventbus
) ,繼續對Android
中Rxjava
的實際開發需求場景進行深入講解 ,有興趣可以繼續關注Carson_Ho的安卓開發筆記