前言
- 在
Andrroid
开发中,网络请求十分常用,而在Android
网络请求库中,Retrofit
是当下最热的一个网络请求库 -
Retrofit
之所以作为现在最流行的网络请求库,其中一个主要原因是:支持RxJava
。Rxjava
由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大Android
开发者的欢迎。 - 今天,我将为大家带来
Retrofit
结合Rxjava
的实际应用案例教学,即常见开发应用场景实现 ,希望大家会喜欢。
Carson带你学RxJava系列文章,包括 原理、操作符、应用场景、背压等等,请关注看文章:Android:这是一份全面 & 详细的RxJava学习指南
目录
1. Retrofit 简介
特别注意:
- 准确来说,Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。
- 原因:网络请求的工作本质上是
OkHttp
完成,而 Retrofit 仅负责 网络请求接口的封装
关于
Retrofit
的更加详细介绍请看文章:这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)
2. RxJava简介
关于
RxJava
的更加详细介绍请看文章:Android Rxjava:这是一篇 清晰 & 易懂的Rxjava 入门教程
3. 二者结合使用
-
Retrofit
之所以作为现在最流行的网络请求库,其中一个主要原因是:支持RxJava
即:
Retrofit
除了提供传统的网络请求方式外,还提供RxJava
版本的 网络请求方式
- 两种方式在使用上最大的区别在于:传统方式采用了
Callback
接口,而RxJava
方式则采用了Observable
接口。主要体现在:- 用于描述网络请求 的接口 的设置
- 网络请求的封装形式 & 发送形式
a. 用于描述网络请求 的接口设置
// 传统方式:Call<..>接口形式
public interface GetRequest_Interface {
@GET("url地址")
Call<Translation> getCall();
// 注解里传入 网络请求 的部分URL地址
// getCall()是接受网络请求数据的方法
}
// RxJava 方式:Observable<..>接口形式
@GET("url地址")
public interface GetRequest_Interface {
Observable<Translation> getCall();
b. 网络请求的封装形式 & 发送形式不同
<-- 传统方式 ->>
// 1. 创建 网络请求接口 的实例
GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
// 2. 采用Call<..>接口 对 发送请求 进行封装
Call<Translation> call = request.getCall();
// 3. 发送网络请求(异步)
call.enqueue(new Callback<Translation>() {
// 请求成功时回调
@Override
public void onResponse(Call<Translation> call, Response<Translation> response) {
...
}
// 请求失败时回调
@Override
public void onFailure(Call<Translation> call, Throwable throwable) {
....
}
});
<-- RxJava 版方式 ->>
// 1. 创建 网络请求接口 的实例
GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
// 2. 采用Observable<...>形式 对 网络请求 进行封装
Observable<Translation> observable = request.getCall();
// 3. 发送网络请求(异步)
observable.subscribeOn(Schedulers.io()) // 在IO线程进行网络请求
.observeOn(AndroidSchedulers.mainThread()) // 回到主线程 处理请求结果
.subscribe(new Observer<Translation>() {
// 发送请求后调用该复写方法(无论请求成功与否)
@Override
public void onSubscribe(Disposable d) {
...// 初始化工作
}
// 发送请求成功后调用该复写方法
@Override
public void onNext(Translation result) {
...// 对返回结果Translation类对象 进行处理
}
// 发送请求成功后,先调用onNext()再调用该复写方法
@Override
public void onComplete() {
Log.d(TAG, "请求成功");
}
// 发送请求失败后调用该复写方法
@Override
public void onError(Throwable e) {
Log.d(TAG, "请求失败");
}
});
}
4. 基础使用
下面,我将采用最基础的 Retrofit + RxJava
实现 网络请求 的功能
4.1 功能说明
- 实现功能:将中文翻译成英文 - > 显示到界面
- 实现方案:采用
Get
方法对 金山词霸API 发送网络请求
- 先切换到工作线程 发送网络请求
- 再切换到主线程进行
UI
更新
4.2 步骤说明
- 添加依赖
- 创建 接收服务器返回数据 的类
- 创建 用于描述网络请求 的接口(区别于传统形式)
- 创建 Retrofit 实例
- 创建 网络请求接口实例 并 配置网络请求参数(区别于传统形式)
- 发送网络请求(区别于传统形式)
- 发送网络请求
- 对返回的数据进行处理
本实例侧重于说明
RxJava
的线程控制,关于Retrofit
的使用请看文章:这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)
4.3 步骤实现
步骤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() {
System.out.println( "Rxjava翻译结果:" + status);
System.out.println("Rxjava翻译结果:" + content.from);
System.out.println("Rxjava翻译结果:" + content.to);
System.out.println("Rxjava翻译结果:" + content.vendor);
System.out.println("Rxjava翻译结果:" + content.out);
System.out.println("Rxjava翻译结果:" + content.errNo);
}
}
步骤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()是接受网络请求数据的方法
}
接下来的步骤均在MainActivity.java内实现(请看注释)
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Rxjava";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//步骤4:创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://fy.iciba.com/") // 设置 网络请求 Url
.addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava
.build();
// 步骤5:创建 网络请求接口 的实例
GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
// 步骤6:采用Observable<...>形式 对 网络请求 进行封装
Observable<Translation> observable = request.getCall();
// 步骤7:发送网络请求
observable.subscribeOn(Schedulers.io()) // 在IO线程进行网络请求
.observeOn(AndroidSchedulers.mainThread()) // 回到主线程 处理请求结果
.subscribe(new Observer<Translation>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Translation result) {
// 步骤8:对返回的数据进行处理
result.show() ;
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "请求失败");
}
@Override
public void onComplete() {
Log.d(TAG, "请求成功");
}
});
}
}
4.4 测试结果
4.5 Demo地址
Carson_Ho的Github地址 = Retrofit结合RxJava实战系列:基础使用
5. 实际开发需求案例
- 下面,我将使用
Retrofit
&RxJava
,并结合实际的开发需求场景进行案例的讲解 - 讲解的实际开发需求场景包括:
5.1 网络请求轮询(无条件)
- 需求场景说明
- 具体实现
具体请看文章:Android RxJava 实际应用讲解:(无条件)网络请求轮询
5.2 网路请求轮询(有条件)
- 需求场景
- 具体实现
具体请看文章:Android RxJava 实际应用讲解:(有条件)网络请求轮询
5.3 网络请求嵌套回调
- 背景
需要进行嵌套网络请求:即在第1个网络请求成功后,继续再进行一次网络请求
如 先进行 用户注册 的网络请求, 待注册成功后回再继续发送 用户登录 的网络请求
- 冲突
嵌套实现网络请求较为复杂,即嵌套调用函数
下面展示的是结合
Retrofit
与RxJava
的基本用法,即未用操作符前
// 发送注册网络请求的函数方法
private void register() {
api.register(new RegisterRequest())
.subscribeOn(Schedulers.io()) //在IO线程进行网络请求
.observeOn(AndroidSchedulers.mainThread()) //回到主线程去处理请求结果
.subscribe(new Consumer<RegisterResponse>() {
@Override
public void accept(RegisterResponse registerResponse) throws Exception {
Toast.makeText(MainActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
login(); //注册成功, 调用登录的方法
}
}, new Consumer<Throwable>() {
@Override
public 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>() {
@Override
public void accept(LoginResponse loginResponse) throws Exception {
Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_SHORT).show();
}
});
}
解决方案
结合RxJava2
中的变换操作符FlatMap()
实现嵌套网络请求具体实现
具体请看文章:
Android RxJava 实际应用讲解:网络请求嵌套回调
5.4 网络请求出错重连
-
需求场景
功能需求说明
- 功能逻辑
- 具体实现
具体请看文章:Android RxJava 实际应用讲解:网络请求出错重连(结合Retrofit)
5.5 合并数据源 & 统一显示
- 需求场景
功能说明
即,同时向2个服务器发送网络请求 ->> 获取数据 ->> 合并数据 ->> 统一展示到客户端具体实现
具体请看文章:Android RxJava 实际应用讲解:合并数据源
至此,关于Retrofit
& RxJava
的实际开发需求场景讲解完毕。
6. Demo地址
上述所有案例的源代码都存放在:Carson_Ho的Github地址 = Retrofit结合RxJava实战系列
7. 总结
- 本文主要讲解了
Retrofit
&RxJava
的结合使用 & 实际开发需求实现 - Carson带你学RxJava系列文章:
入门
Carson带你学Android:这是一篇清晰易懂的Rxjava入门教程
Carson带你学Android:面向初学者的RxJava使用指南
Carson带你学Android:RxJava2.0到底更新了什么?
原理
Carson带你学Android:图文解析RxJava原理
Carson带你学Android:手把手带你源码分析RxJava
使用教程:操作符
Carson带你学Android:RxJava操作符教程
Carson带你学Android:RxJava创建操作符
Carson带你学Android:RxJava功能性操作符
Carson带你学Android:RxJava过滤操作符
Carson带你学Android:RxJava组合/合并操作符
Carson带你学Android:RxJava变换操作符
Carson带你学Android:RxJava条件/布尔操作符
实战
Carson带你学Android:什么时候应该使用Rxjava?(开发场景汇总)
Carson带你学Android:RxJava线程控制(含实例讲解)
Carson带你学Android:图文详解RxJava背压策略
Carson带你学Android:RxJava、Retrofit联合使用汇总(含实例教程)
Carson带你学Android:优雅实现网络请求嵌套回调
Carson带你学Android:网络请求轮询(有条件)
Carson带你学Android:网络请求轮询(无条件)
Carson带你学Android:网络请求出错重连(结合Retrofit)
Carson带你学Android:合并数据源
Carson带你学Android:联想搜索优化
Carson带你学Android:功能防抖
Carson带你学Android:从磁盘/内存缓存中获取缓存数据
Carson带你学Android:联合判断
欢迎关注Carson_Ho的简书
不定期分享关于安卓开发的干货,追求短、平、快,但却不缺深度。