1. 需求场景

2. 功能说明

  • 功能需求说明

  • 功能逻辑

 实例说明
在本例子中:采用Get方法对 金山词霸API 发送网络请求

  1. 通过 断开网络连接 模拟 网络异常错误(恢复网络即可成功发送请求)
  2. 限制重试次数 = 10次
  3. 采用 Gson 进行数据解析

3. 具体实现

下面,我将结合 RetrofitRxJava 实现 网络请求出错重连 功能

3.1 步骤说明

  1. 添加依赖
  2. 创建 接收服务器返回数据 的类
  3. 创建 用于描述网络请求 的接口(区别于Retrofit传统形式)
  4. 创建 Retrofit 实例
  5. 创建 网络请求接口实例 并 配置网络请求参数(区别于Retrofit传统形式)
  6. 发送网络请求(区别于Retrofit传统形式)
  7. 发送网络请求
  8. 对返回的数据进行处理

下面,将进行详细的功能说明。

本实例侧重于说明 RxJava 的轮询需求,关于Retrofit的使用请看文章:这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)

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;@Overrideprotected 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<?>>() {@Overridepublic ObservableSource<?> apply(@NonNull Observable<Throwable> throwableObservable) throws Exception {// 参数Observable<Throwable>中的泛型 = 上游操作符抛出的异常,可通过该条件来判断异常的类型return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {@Overridepublic 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>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(Translation result) {// 接收服务器返回的数据Log.d(TAG,  "发送成功");result.show();}@Overridepublic void onError(Throwable e) {// 获取停止重试的信息Log.d(TAG,  e.toString());}@Overridepublic void onComplete() {}});}
}

3.3 测试结果

  1. 一开始先通过 断开网络连接 模拟 网络异常错误,即开始重试;
  2. 等到第4次重试后恢复网络连接,即无发生网络异常错误,此时重试成功

Android RxJava操作符的学习---功能性操作符--网络请求出错重连(结合Retrofit)相关推荐

  1. Android RxJava操作符的学习---功能性操作符--(有条件)网络请求轮询(结合Retrofit)

    1. 需求场景 2. 功能说明 采用Get方法对 金山词霸API 按规定时间重复发送网络请求,从而模拟 轮询 需求实现 停止轮询的条件 = 当轮询到第4次时 采用 Gson 进行数据解析 3. 具体实 ...

  2. Android RxJava操作符的学习---功能性操作符

    3.4 功能性操作符 作用 辅助被观察者(Observable) 在发送事件时实现一些功能性需求 实际应用场景 连接(订阅) 观察者 & 被观察者 线程调度(切换) 错误处理 事件生命周期操作 ...

  3. Android RxJava操作符的学习---变换操作符---网络请求嵌套回调

    变换操作符的主要开发需求场景 = 嵌套回调(Callback hell) 下面,我将采用一个实际应用场景实例来讲解嵌套回调(Callback hell) 1. 需求场景 1.1 背景 需要进行嵌套网络 ...

  4. Android RxJava操作符的学习---创建操作符--(无条件)网络请求轮询

    1. 需求场景 2. 功能说明 本文将采用Get方法对 金山词霸API 按规定时间 重复发送网络请求,从而模拟 轮询 需求实现 采用 Gson 进行数据解析 3. 具体实现 下面结合 Retrofit ...

  5. android 网络时区 错误,React native 安卓机器上调试代码报错:网络请求出错TypeError: Network request failed...

    React native 安卓机器上调试代码报错:网络请求出错TypeError: Network request failed 安卓机器 usb连接调试 报错信息 TypeError: Networ ...

  6. Android 9.0/P(android p指安卓9.0版本) okhttp3网络请求出错

    已经在AndroidManifest.xml申请网络权限,在8.0以下的系统中网络访问正常,但是9.0中出现网络请求失败 Android 9.0的网络请求失败如下图: 出现这个错误的原因是:从Andr ...

  7. Android RxJava操作符的学习---过滤操作符----功能防抖

    1. 需求场景 2. 功能说明 3. 具体实现 // 注册控件Button button;button = (Button)findViewById(R.id.button);/** 1. 此处采用了 ...

  8. Android RxJava操作符的学习---过滤操作符

    3.5 过滤操作符 作用 过滤 / 筛选 被观察者(Observable)发送的事件 & 观察者 (Observer)接收的事件 应用场景 根据 指定条件 过滤事件 根据 指定事件数量 过滤事 ...

  9. Android RxJava操作符的学习---创建操作符

    RxJava如此受欢迎的原因,在于其提供了丰富 & 功能强大的操作符,几乎能完成所有的功能需求 1. 简介 RxJava 操作符的具体简介如下: 2. 类型 RxJava功能强大,所以其对应的 ...

最新文章

  1. Python3中迭代器介绍
  2. 对RPM软件包的查询操作
  3. 28和lba48命令格式区别_linux硬盘分区、格式化、挂载超详细步骤
  4. Hadoop之HDFS应用
  5. docker依赖的Linux内核特性及各命令参数说明
  6. git回退到历史版本并提交到远程分支
  7. 赋值语句、变量、数学表达式、位运算详解(C++)
  8. 关于动网论坛、动力起航、自由动力、动易、动感购物、乔客、织梦CMS.
  9. 科来网络回溯分析系统-回溯追踪ARP扫描攻击
  10. Oracle卸载(无universal installer)
  11. 在mac上使用nginx配置codeigniter框架一直显示404的问题的一种方法(重启)
  12. Go语言优秀的Revel开源框架推荐
  13. 信号偏移成为边界地区呼吸的痛
  14. 一个Android开发者开博一周年的成长日记——送给不知如何下手的【初级开发者】和【在校生】
  15. 微博粉丝精灵_天猫精灵“布蕉绿”新品上线,解锁智能音箱潮流新玩法!
  16. QImage 图像格式小结 Format_RGB32
  17. 展望 | 2023年十大科技趋势
  18. 亲缘进程、非亲缘进程-共享内存与信号
  19. Epic 起诉苹果,G 胖无辜背锅,要求其公开数百款第三方游戏 6 年的数据,网友:G 胖实冤!...
  20. WireShark的下载与安装

热门文章

  1. 微信公众号开发(二)基础接口
  2. 精妙SQL语句(转载)
  3. win10系统找不到以太网该怎么办
  4. STM32CubeF4 1.24.1版本的固件库安装
  5. 关于Mac App Store无法下载、无法安装、一直转圈的解决方法
  6. 这一届欧洲程序猿没几个能打的
  7. 计算机考试三级网络技术复习一
  8. npskins 可直接取回CSGO开箱网站
  9. HDFS黑名单退役服务器
  10. 她说 | Women in Open Source