• 变换操作符的主要开发需求场景 = 嵌套回调(Callback hell
  • 下面,我将采用一个实际应用场景实例来讲解嵌套回调(Callback hell

1. 需求场景

1.1 背景

需要进行嵌套网络请求:即在第1个网络请求成功后,继续再进行一次网络请求

如 先进行 用户注册 的网络请求, 待注册成功后回再继续发送 用户登录 的网络请求

1.2 冲突

嵌套实现网络请求较为复杂,即嵌套调用函数

下面展示的是结合 RetrofitRxJava的基本用法,即未用操作符前

// 发送注册网络请求的函数方法private void register() {api.register(new RegisterRequest()).subscribeOn(Schedulers.io())               //在IO线程进行网络请求.observeOn(AndroidSchedulers.mainThread())  //回到主线程去处理请求结果.subscribe(new Consumer<RegisterResponse>() {@Overridepublic void accept(RegisterResponse registerResponse) throws Exception {Toast.makeText(MainActivity.this, "注册成功", Toast.LENGTH_SHORT).show();login();   //注册成功, 调用登录的方法}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {Toast.makeText(MainActivity.this, "注册失败", Toast.LENGTH_SHORT).show();}});}// 发送登录网络请求的函数方法
private void login() {api.login(new LoginRequest()).subscribeOn(Schedulers.io())               //在IO线程进行网络请求.observeOn(AndroidSchedulers.mainThread())  //回到主线程去处理请求结果.subscribe(new Consumer<LoginResponse>() {@Overridepublic void accept(LoginResponse loginResponse) throws Exception {Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_SHORT).show();}});}

1.3 解决方案

结合 RxJava2中的变换操作符FlatMap()实现嵌套网络请求

2. 功能说明

  • 实现功能:发送嵌套网络请求(将英文翻译成中文,翻译两次)
  1. 为了让大家都能完成Demo,所以通过 公共的金山词霸API 来模拟 “注册 - 登录”嵌套网络请求
  2. 即先翻译 Register(注册),再翻译 Login(登录)
  • 实现方案:采用Get方法对 金山词霸API 发送网络请求

采用 Gson 进行数据解析

3. 具体实现

下面我将结合 RetrofitRxJava 实现网络请求嵌套

3.1 步骤说明

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

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 的数据格式,创建 接收服务器返回数据 的类:

为了演示是2个网络请求,所以对应设置2个接收服务器的数据类

<-- Translation1.java -->
public class Translation1 {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);}
}<-- Translation2.java -->
public class Translation2 {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 {// 网络请求1@GET("ajax.php?a=fy&f=auto&t=auto&w=hi%20register")Observable<Translation1> getCall();// 网络请求2@GET("ajax.php?a=fy&f=auto&t=auto&w=hi%20login")Observable<Translation2> getCall_2();// 注解里传入 网络请求 的部分URL地址// Retrofit把网络请求的URL分成了两部分:一部分放在Retrofit对象里,另一部分放在网络请求接口里// 如果接口里的url是一个完整的网址,那么放在Retrofit对象里的URL可以忽略// 采用Observable<...>接口// getCall()是接受网络请求数据的方法}

接下来的步骤均在MainActivity.java内实现(请看注释)

MainActivity.java

public class MainActivity extends AppCompatActivity {private static final String TAG = "Rxjava";// 定义Observable接口类型的网络请求对象Observable<Translation1> observable1;Observable<Translation2> observable2;@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<...>形式 对 2个网络请求 进行封装observable1 = request.getCall();observable2 = request.getCall_2();observable1.subscribeOn(Schedulers.io())               // (初始被观察者)切换到IO线程进行网络请求1.observeOn(AndroidSchedulers.mainThread())  // (新观察者)切换到主线程 处理网络请求1的结果.doOnNext(new Consumer<Translation1>() {@Overridepublic void accept(Translation1 result) throws Exception {Log.d(TAG, "第1次网络请求成功");result.show();// 对第1次网络请求返回的结果进行操作 = 显示翻译结果}}).observeOn(Schedulers.io())                 // (新被观察者,同时也是新观察者)切换到IO线程去发起登录请求// 特别注意:因为flatMap是对初始被观察者作变换,所以对于旧被观察者,它是新观察者,所以通过observeOn切换线程// 但对于初始观察者,它则是新的被观察者.flatMap(new Function<Translation1, ObservableSource<Translation2>>() { // 作变换,即作嵌套网络请求@Overridepublic ObservableSource<Translation2> apply(Translation1 result) throws Exception {// 将网络请求1转换成网络请求2,即发送网络请求2return observable2;}}).observeOn(AndroidSchedulers.mainThread())  // (初始观察者)切换到主线程 处理网络请求2的结果.subscribe(new Consumer<Translation2>() {@Overridepublic void accept(Translation2 result) throws Exception {Log.d(TAG, "第2次网络请求成功");result.show();// 对第2次网络请求返回的结果进行操作 = 显示翻译结果}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) throws Exception {System.out.println("登录失败");}});}
}

3.3 测试结果

Android RxJava操作符的学习---变换操作符---网络请求嵌套回调相关推荐

  1. Android RxJava操作符的学习---变换操作符

    3.2 变换操作符 3.2.1.作用 对事件序列中的事件 / 整个事件序列 进行加工处理(即变换),使得其转变成不同的事件 / 整个事件序列 具体原理 3.2.2.作用类型 应用场景 嵌套回调(Cal ...

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

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

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

    1. 需求场景 2. 功能说明 功能需求说明 功能逻辑  实例说明 在本例子中:采用Get方法对 金山词霸API 发送网络请求 通过 断开网络连接 模拟 网络异常错误(恢复网络即可成功发送请求) 限制 ...

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

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

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

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

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

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

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

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

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

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

  9. Android RxJava(一) create操作符的用法和源码分析

    RxJava(一) create操作符的用法和源码分析 转载于:https://www.cnblogs.com/zhujiabin/p/7291901.html

最新文章

  1. 新晋院士:直到硕士毕业前都想做公务员,现在只对科研感兴趣
  2. 国家微生物科学数据中心推出免费一站式生物信息分析云平台
  3. TeamViewer试用期满转免费版本方法
  4. git永久保存账号密码
  5. python中扑克牌类设计_Python中的计数 Counter类
  6. 如何搭建一套完整的深度学习系统?
  7. Linux下必须知道的网络命令(持续更新)
  8. NHibernate Linq中Null值排序的解决方法
  9. java实现支付宝第三方登录_Java 实现QQ第三方登录(附赠:完整代码)
  10. android源码编译的小小总结
  11. php如何只删去汉字,php如何删除字符串中的中文
  12. 用continue计算100以内奇数和_一分钟明白break和continue
  13. python绘制彩色地震剖面断层解释_地震剖面上断层的识别标志主要有哪些
  14. opengl——绘制一个点
  15. php车牌识别,跨平台车牌识别应用 Light-LPR
  16. HyperMesh 实用教程(一)组件
  17. 如何将PDF文档转成Excel?
  18. IBM罗睿兰的“告别信”
  19. Android端手机测试体系
  20. 2020 消防系统解决方案说明

热门文章

  1. Windows安装MySQL 5.7报错:Can‘t find error-message file ‘XXX\share\errmsg.sys‘
  2. 史上最简单MYSQL教程详解(基础篇)之初识MySQL数据库以及环境配置
  3. JAVA语言实现的简单ATM提款机系统
  4. Linux中的shell到底是什么?
  5. Android Drawable Resource学习(五)、StateListDrawable
  6. 微信客服对接-唯一客服系统文档中心
  7. 微信移动端(wap)开发调试工具
  8. 关于移动端页面开发(微信内置浏览器)总结
  9. 人工智能——多算法组合与模型最优
  10. Bad Request This combination of host and port requires TLS.