Android:RxJava 結合 Retrofit 全面實現 網路請求出錯重連
前言
Rxjava
,由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大Android
開發者的歡迎。
RxJava
如此受歡迎的原因,在於其提供了豐富 & 功能強大的操作符,幾乎能完成所有的功能需求- 今天,我將為大家帶來
Rxjava
建立操作符的實際開發需求場景:網路請求出錯重連需求 ,並結合Retrofit
與RxJava
實現,希望大家會喜歡。
- 本系列文章主要基於
Rxjava 2.0
- 接下來的時間,我將持續推出
Android
中Rxjava 2.0
的一系列文章,包括原理、操作符、應用場景、背壓等等 ,有興趣可以繼續關注Carson_Ho的安卓開發筆記!!
目錄
1. 需求場景
2. 功能說明
- 功能需求說明
- 功能邏輯
- 例項說明
在本例子中:採用Get
方法對 金山詞霸API 傳送網路請求
- 通過 斷開網路連線 模擬 網路異常錯誤(恢復網路即可成功傳送請求)
- 限制重試次數 = 10次
- 採用
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 RxJavafixRetrofit2 extends AppCompatActivity {
private static final String TAG = "RxJava";
// 設定變數
// 可重試次數
private int maxConnectCount = 10;
// 當前已重試次數
private int currentRetryCount = 0;
// 重試等待時間
private int waitRetryTime = 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:傳送網路請求 & 通過retryWhen()進行重試
// 注:主要異常才會回撥retryWhen()進行重試
observable.retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(@NonNull Observable<Throwable> throwableObservable) throws Exception {
// 引數Observable<Throwable>中的泛型 = 上游操作符丟擲的異常,可通過該條件來判斷異常的型別
return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(@NonNull Throwable throwable) throws Exception {
// 輸出異常資訊
Log.d(TAG, "發生異常 = "+ throwable.toString());
/**
* 需求1:根據異常型別選擇是否重試
* 即,當發生的異常 = 網路異常 = IO異常 才選擇重試
*/
if (throwable instanceof IOException){
Log.d(TAG, "屬於IO異常,需重試" );
/**
* 需求2:限制重試次數
* 即,當已重試次數 < 設定的重試次數,才選擇重試
*/
if (currentRetryCount < maxConnectCount){
// 記錄重試次數
currentRetryCount++;
Log.d(TAG, "重試次數 = " + currentRetryCount);
/**
* 需求2:實現重試
* 通過返回的Observable傳送的事件 = Next事件,從而使得retryWhen()重訂閱,最終實現重試功能
*
* 需求3:延遲1段時間再重試
* 採用delay操作符 = 延遲一段時間傳送,以實現重試間隔設定
*
* 需求4:遇到的異常越多,時間越長
* 在delay操作符的等待時間內設定 = 每重試1次,增多延遲重試時間1s
*/
// 設定等待時間
waitRetryTime = 1000 + currentRetryCount* 1000;
Log.d(TAG, "等待時間 =" + waitRetryTime);
return Observable.just(1).delay(waitRetryTime, TimeUnit.MILLISECONDS);
}else{
// 若重試次數已 > 設定重試次數,則不重試
// 通過傳送error來停止重試(可在觀察者的onError()中獲取資訊)
return Observable.error(new Throwable("重試次數已超過設定次數 = " +currentRetryCount + ",即 不再重試"));
}
}
// 若發生的異常不屬於I/O異常,則不重試
// 通過返回的Observable傳送的事件 = Error事件 實現(可在觀察者的onError()中獲取資訊)
else{
return Observable.error(new Throwable("發生了非網路異常(非I/O異常)"));
}
}
});
}
}).subscribeOn(Schedulers.io()) // 切換到IO執行緒進行網路請求
.observeOn(AndroidSchedulers.mainThread()) // 切換回到主執行緒 處理請求結果
.subscribe(new Observer<Translation>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Translation result) {
// 接收伺服器返回的資料
Log.d(TAG, "傳送成功");
result.show();
}
@Override
public void onError(Throwable e) {
// 獲取停止重試的資訊
Log.d(TAG, e.toString());
}
@Override
public void onComplete() {
}
});
}
}
3.3 測試結果
- 一開始先通過 斷開網路連線 模擬 網路異常錯誤,即開始重試;
- 等到第3次重試後恢復網路連線,即無發生網路異常錯誤,此時重試成功
4. Demo地址
5. 總結
- 本文主要講解了
Rxjava
建立操作符的實際開發需求場景:網路請求出錯重連需求 ,並結合Retrofit
與RxJava
實現 - 下面我將結合 實際場景應用 &
Rxjava
的相關使用框架(如Retrofit
、Eventbus
) ,繼續對Android
中Rxjava
的實際開發需求場景進行深入講解 ,有興趣可以繼續關注Carson_Ho的安卓開發筆記
幫頂 / 評論點贊!因為你的鼓勵是我寫作的最大動力!
相關推薦
Android:RxJava 結合 Retrofit 全面實現 網路請求出錯重連
前言 Rxjava,由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大 Android開發者的歡迎。 RxJava如此受歡迎的原因,在於其提供了豐富 & 功能強大的操作符,幾乎能完成所有的功能需求 今天,我將為
Android:RxJava 結合 Retrofit 優雅實現 網路請求輪詢
前言 Rxjava,由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大 Android開發者的歡迎。 RxJava如此受歡迎的原因,在於其提供了豐富 & 功能強大的操作符,幾乎能完成所有的功能需求 今天,我將為
Android RxJava操作符的學習---功能性操作符--網路請求出錯重連(結合Retrofit)
1. 需求場景 2. 功能說明 功能需求說明 功能邏輯 例項說明 在本例子中:採用Get方法對 金山詞霸API 傳送網路請求 通過 斷開網路連線 模擬 網路異常錯誤(恢復網路即可
Android小知識-剖析Retrofit中的網路請求流程以及相關引數
本平臺的文章更新會有延遲,大家可以關注微信公眾號-顧林海,包括年底前會更新kotlin由淺入深系列教程,目前計劃在微信公眾號進行首發,如果大家想獲取最新教程,請關注微信公眾號,謝謝! 在使用Retrofit時,需要建立Retrofit的例項,定義一個網路請求介面併為介面中的方法添加註解,接著通過動
Android RxJava 實戰系列:優雅實現 網路請求巢狀回撥
轉自-----http://blog.csdn.net/carson_ho/article/details/78315696,請為大神打call 前言 Rxjava,由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大 Android
Android RxJava 實戰講解:優雅實現 網路請求輪詢
轉自-----http://blog.csdn.net/carson_ho/article/details/78256466 前言 Rxjava,由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大 Android開發者的歡迎。
Retrofit + Rxjava + RxAndroid實現網路請求
之前自己實現了一個新聞類閱讀APP,最近想使用當下流行的Retrofit + Rxjava + RxAndroid + MVP架構來重構一下,本文以每日一文作為資料來源API做一個簡單的示例,來介紹一下如何使用Retrofit + Rxjava + RxAndr
Android--menu和OkHttp框架(未封裝),結合Executors(執行緒池)實現網路請求的案例
涉及到的 知識點: 1.安卓UI元件menu 2.OkHttp框架 3.Executors(執行緒池) OkHttp結構簡介 案例程式碼 import android.os.Bundle; import android.suppo
Android:RxJava的使用
說明: RxJava用於非同步執行任務,跟建立子執行緒執行任務無本質區別,優點在於讓程式碼看起來整潔優雅些,並不能減少程式碼量 一、加入jar包依賴(app下的build.gradle): dependencies { ... compile 'i
android:使用small一步步實現外掛化與熱更新
由於外掛化開發與熱更新最近貌似越來越火,新開的專案準備也使用外掛化進行開發!其中遇到不少坑,在這裡寫了一個小的例子,記錄一下開發流程,有助於自己,同時希望能夠幫助大家理解,並且對於自身專案接入外掛化有所幫助! 外掛化 效果: 外掛化開發的含義:
RxJava+Retrofit2+MVP實現網路請求
上一遍部落格介紹了RxJava+Retrofit2的使用。在前段時間,刷招聘簡歷的時候,發現有一部分的公司會要求MVP模式的理解和具體使用。在現在越來越複雜的業務,我們的Activity的負擔也是越來越大,因此接著這篇我結合MVP模式來介紹一下自己對RxJava
RxJava結合Retrofit如何避免覆蓋http請求(終端當前http請求)
unSubscribe("goodsListSubscribe");//取消前一次的http請求,避免頻繁請求導致響應次序及資料混亂 Subscription subscribe = goodsDAL.queryGoodsList(firstCategoryId, s
Android使用HttpUrlConnection來實現網路請求,親測有效
產品提出需求,需要再視訊播放完畢後把當前的播放位置上傳給伺服器。作為一名不愛造輪子的程式設計師,我果斷的使用了三方的視屏播放器,以module依賴的形式匯入到了工程,也由此產生了一個問題,三方module沒有Application的,也就無法進行整合OkGo來進行簡單的網路請
Android開發,使用Retrofit發送HTTP請求
service fin tps protect convert exceptio code find content 在build.gradle(Module: app)中加入 dependencies { ... implementation ‘com.
Swift使用Alamofire實現網路請求
Alamofire是一個用Swift編寫的HTTP網路庫,由此前熱門開源專案AFNetworking的的作者mattt開發,可非常簡單地用於非同步網路通訊。 要獲取最新版本的 Alamofire,前往https://github.com/Alamofire/Alamofire然後單擊網頁右邊
OKHTTP-RecyclerView實現網路請求資料
build.gradle中匯入需要依賴 implementation ‘com.google.code.gson:gson:2.8.5’ implementation ‘com.android.support:design:27.1.1’ compile ‘cn.yipianfengye
android快取框架ASimpleCache的使用 (網路請求資料並快取)
官方簡介: ASimpleCache 是一個為Android制定的 輕量級的 開源快取框架。輕量到只有一個java檔案(由十幾個類精簡而來)。 框架地址 1、它可以快取什麼東西? 普通的字串、JsonObject、JsonArray、Bitmap、Drawable、
解析Node.js通過axios實現網路請求
本次給大家分享一篇node.js通過axios實現網路請求的方法,寫的十分的全面細緻,具有一定的參考價值,對此有需要的朋友可以參考學習下。如有不足之處,歡迎批評指正。 1、使用Npm 下載axios npm install --save axios var update_u
iOS NSURLSession 實現網路請求-檔案下載-上傳-後臺下載
* 會話NSURLSession NSURLConnection通過全域性狀態來管理cookies, 認證資訊等公共資源, 如果兩個連線需要使用不同的資源配置情況時就無法解決, 這個問題在NSURLSession可以解決, NSURLSession同
[Swift通天遁地]四、網路和執行緒-(4)使用Alamofire實現網路請求
本文將演示如何使用第三方庫實現網路請求服務。 首先確保在專案中已經安裝了所需的第三方庫。 點選【Podfile】,檢視安裝配置檔案。 1 source 'https://github.com/CocoaPods/Specs.git' 2 platform :ios, '12.0' 3 use_