内容简介:Android:你该如何结合Retrofit 与 RxJava使用(含使用教程)
前言
- 在
Andrroid
开发中,网络请求十分常用,而在Android
网络请求库中,Retrofit
是当下最热的一个网络请求库
-
Retrofit
之所以作为现在最流行的网络请求库,其中一个主要原因是: 支持RxJava
。Rxjava
由于其 基于事件流的链式调用、逻辑简洁 & 使用简单 的特点,深受各大Android
开发者的欢迎。
- 今天,我将为大家带来
Retrofit
结合Rxjava
的 实际应用案例教学 ,即 常见开发应用场景实现 ,希望大家会喜欢。
本文主要基于 Retrofit 2.0
& Rxjava 2.0
1. 本系列文章主要基于 Rxjava 2.0
2. 接下来的时间, 我将持续推出 Android
中 Rxjava 2.0
的一系列文章,包括原理、操作符、应用场景、背压等等 ,有兴趣可以继续关注 Carson_Ho的安卓开发笔记 !!
目录
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 网络请求轮询(无条件)
- 需求场景说明
5.2 网路请求轮询(有条件)
- 需求场景
-
具体实现
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()
实现嵌套网络请求
5.4 网络请求出错重连
-
需求场景
-
功能需求说明
- 功能逻辑
-
具体实现
5.5 合并数据源 & 统一显示
- 需求场景
-
功能说明
即,同时向2个服务器发送网络请求 ->> 获取数据 ->> 合并数据 ->> 统一展示到客户端
-
具体实现
具体请看文章: Android RxJava 实际应用讲解:合并数据源
至此,关于 Retrofit
& RxJava
的实际开发需求场景讲解完毕。
6. Demo地址
上述所有案例的源代码都存放在: Carson_Ho的Github地址 = Retrofit结合RxJava实战系列
7. 总结
- 本文主要讲解了
Retrofit
&RxJava
的结合使用 & 实际开发需求实现 - 下面,我将继续深入讲解
Rxjava
的其他实际开发需求场景 (结合相关框架,如RxBinding
、Eventbus
),有兴趣可以继续关注 Carson_Ho的安卓开发笔记
请帮顶 / 评论点赞!因为你的鼓励是我写作的最大动力!
以上所述就是小编给大家介绍的《Android:你该如何结合Retrofit 与 RxJava使用(含使用教程)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- NServiceBus 结合 RabbitMQ 使用教程
- 结合案例使用 Java 注解和反射
- Apache使用fcgi方式与PHP结合
- Redux 基础教程以及结合 React 使用方式
- laravel-admin 与 vue 结合使用
- 使用socket.io与express结合,体验websocket
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。