RxJava2 实战知识梳理(4) - 结合 Retrofit 请求新闻资讯
前言
如何通过结合Retrofit
框架来进行网络请求,也是RxJava
的学习过程中必须要掌握的一环。网上已经有很多开源项目和文章介绍了,今天这篇文章,我们就通过一个简单的例子,通过RxJava + Retrofit
的方式实现网络请求。
这个例子很简单,我们通过 干货集中营 提供的接口,分别请求Android
类和iOS
类的资讯,并将这两个接口所返回的数据在界面上进行展示。
通过该例子,可以学习如何将Retrofit
和RxJava
结合,并通过zip
操作符实现等待多个网络请求完成。
示例
2.1 接口介绍
首先来熟悉一下所用到的测试接口,其数据来自于 干货集中营,这里选择Android
和iOS
两类的资讯,通过接口的描述,可以知道发起请求时的变量包含三个:
- 分类
- 请求个数
- 请求页数
返回的数据格式如下:
2.2 编写 Entity 类
根据分析好的数据格式,我们编写对应的Entity
类:
- 单次返回结果的数据结构:
- 单条资讯的数据结构:
2.3 引入 Retrofit 依赖
接下来,在build.gradle
文件中,引入必要的依赖,以下三个依赖包的作用分别为:
-
Retrofit
的核心库 - 将返回的
Call<Response>
转换成Call<NewsEntity>
- 将
Call<NewsEntity>
转换成Observable<NewsEntity>
2.4 定义 Retrofit 需要的请求接口
按照Retrofit
的使用介绍,我们需要定义一个接口类,这个接口类的返回值为Observable<NewsEntity>
,也就是我们之前定义好的数据结构。而这个接口接收三个参数:请求类型、请求个数、请求所在页数。
当我们需要请求数据时,就应当像下面这样构造一个Observable<NewsEntity>
:
-
baseUrl
:定义请求链接的前缀 -
addConverterFactory
:将OKHttp
返回的标准Response
解析成我们所需要的数据类型NewsEntity
-
addCallAdapterFactory
:将Call<NewsEntity>
转换成Observable<NewsEntity>
,这样才能真正将Retrofit
和RxJava
结合起来。
2.5 发起请求
以上就是所有的准备工作,回顾一下我们主要做了以下四步,这也是今后我们使用其它任意接口时的标准流程:
- 熟悉接口
- 根据接口返回的数据,定义
Entity
- 根据接口的
url
组成方式定义Retrofit
所需要的接口声明,接口函数的返回类型为Observable<Entity>
,其中Entity
就是第二步中定义好的返回数据类型。 - 通过
Retrofit
,根据第三步的接口定义,返回真正的Observable
。
其实经过以上的四步,我们的工作就基本上完成了,只需要把上面第四步中返回的Observable<XXXEntity>
当做一个发送数据的普通数据源就可以了。
示例代码如下,我们请求了Android
和iOS
两个接口,并且使用zip
操作符让两个接口都返回之后,才将数据呈现给用户,同时每次点击刷新资讯之后,我们将页数增加一以请求新的资讯。
示例解析
关于如何使用Retrofit + RxJava
前面已经说得比较清楚了,下面我们重点介绍一下新接触的两个操作符,flatMap
和zip
。
3.1 flatMap
flatMap
的原理图如下所示:
它接收一个Function
函数,对于上游发送的每个事件它都会应用该函数,这个函数返回一个新的Observable
,如果有多个Observable
,那么他会发送合并后的结果。
在上面的例子中,上游的just
发送一个请求的所在页数,我们根据这个页数再去创建一个新的Observable
来发送数据。
3.2 zip
zip
操作符的原理图如下所示:
它接收多个Observable
,以及一个函数,该函数的形参为这些Observable
发送的数据,并且要等所有的Observable
都发射完会后才会回调该函数。
通过zip
操作符,我们就可以实现等待多个网络请求完成再返回的需求,例如在上面的例子中,我们会等待Android
和iOS
类的资讯请求都返回之后,再合并它们的结果发送给下游,在界面上展示。
最后
关于rxjava更多的实战,推荐此文:
Novate 一款Android RxStyle的网络框架
- 剑指OFFER之打印1到最大的N位数(九度OJ1515)
- GridView实战二:使用ObjectDataSource数据源控件
- javascript实例:逐条记录停顿的走马灯
- Python标准库05 存储对象 (pickle包,cPickle包)
- macOS平台下虚拟摄像头的研发总结
- 网页优化系列三:使用压缩后置viewstate
- 网页优化系列三:使用压缩后置viewstate
- macOS下利用dSYM文件将crash文件中的内存地址转换为可读符号
- 微信小程序的大动作
- Python标准库04 文件管理 (部分os包,shutil包)
- 手把手教你Dojo入门
- location的hash部分和使用window.onhashchange实现ajax请求内容时使用浏览器后退和前进功能
- 协议森林01 邮差与邮局 (网络协议概观)
- Mac OS平台下应用程序安装包制作工具Packages的使用介绍
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- hugo-页面变量
- 将hexo文章头转为hugo格式
- python 技术篇-使用pytesseract库进行图像识别之环境配置
- Linux 安装PicGo问题
- 【剑指Offer】对称的二叉树
- deepin下状态栏无法显示问题
- 【剑指Offer】二叉树的镜像
- Python实战之利用数据字典实现井字棋盘,
- scRNA-seq Clustering quality control
- Python实战之tkinter库画图,用canver画布教你画卡通人物!
- Python教程之正则表达式(基础篇)
- Python教程之正则表达式(提高篇)
- 【剑指Offer】树的子结构
- 【剑指Offer】合并两个排序的链表
- Python实战之特定文本提取,挑战高效办公的第一步