Android RxJava与Retrofit结合使用详解
作者:萌动小彩笔 发布时间:2021-10-19 20:10:53
如今RxJava和Retrofit的结合使用估计已经相当普遍了,自己工作中也是一直都在使用。在使用的过程中我们都会对其进行封装使用,GitHub上也有很多封装好的项目可以直接拿来使用,其实对于开源框架的二次封装有时候针对不同的业务逻辑封装的过程中也多多少少有些不同,建议还是自己动手去封装使用。这样不仅提升自己对原框架的理解,还可以提高自己的封装能力。在工作过程中如需要改动便更加容易入手。好了,废话不多说,这里做了一个简单的样本供大家参考。
添加依赖
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'io.reactivex.rxjava2:rxjava:2.x.y'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
添加依赖本并不想多说,我想大家都知道,但是对于刚接触这些知识的时候我想有没有人在看网上的文章时会觉得有些依赖是在哪找到并添加的呢?例如:com.squareup.retrofit2:converter-gson:2.3.0
我们要添加一个GsonConverter
的依赖。对于刚接触这些知识和不经常逛GitHub的人来说会不会一脸懵逼呢?不管会不会,反正我第一次接触的时候确实懵逼了下。这里给那些懵逼过的人提示下,我们可以通过打开GitHub上项目的子文件查看到相应的依赖。比如GitHub上Retrofit项目中:retrofit/retrofit-converters/gson/
这个路径下就可以查看到相应的GsonConverter
的依赖。
封装Retrofit(单例模式)
public class HttpRequest {
public static final long CONNECTTIME = 30000;
public static final String BASE_URL = "http://jxhdapi.ooowin.com/";
private ApiService apiService;
public HttpRequest() {
//添加日志 *
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.d("TAG", "==========" + message);
}
}).setLevel(HttpLoggingInterceptor.Level.BODY);
//获取OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(CONNECTTIME, TimeUnit.MICROSECONDS)
.readTimeout(CONNECTTIME,TimeUnit.MICROSECONDS)
.writeTimeout(CONNECTTIME,TimeUnit.MICROSECONDS)
.addInterceptor(interceptor)
.addNetworkInterceptor(new HttpHeaderInterceptor())
.build();
//初始化Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
apiService = retrofit.create(ApiService.class);
}
// 创建单例
private static class SingletonHolder {
private static final HttpRequest INSTANCE = new HttpRequest();
}
public static ApiService getApi(){
return SingletonHolder.INSTANCE.apiService;
}
}
这里我们可以看到添加了两个 * :日志 * 和网络请求Header * ,我们都知道对于Retrofit我们是可以直接通过GsonConverter
转换成实体类的,但有的时候我们又想去获取它的json数据进行查看,这个时候我们就可以通过添加日志 * 实现,但一定要给它设置setLevel
方法,设置不同的属性打印出来的数据是不一样的。至于添加Header * 我想大家都应该知道,正常工作中接口所需要的Header都是相同的,所以我们要进行统一添加:
public class HttpHeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request build = request.newBuilder()
// .addHeader("","") 添加header
.build();
return chain.proceed(build);
}
}
封装实体类
{
"code": 1,
"msg": "操作成功",
"data": {······}
}
通常我们从服务端拿到的json数据就像上面那样,有些返回的字段内容格式是固定的,比如:code和msg。有些则是不确定,如:data。这个时候我们就需要对其进行二次处理了,我们可以写一个基类:
public class BaseBean<T> {
private int code;
private String msg;
private T data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
利用泛型来表示data中的不确定格式的数据,这里用一个获取全国所有省的数据接口进行测试:
public interface ApiService {
//获取省列表
@GET("common/areas")
Flowable<BaseBean<List<Province>>> province();
}
实体类封装好后我们可以进行一下测试:
HttpRequest.getApi()
.province()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<BaseBean<List<Province>>>() {
@Override
public void onSubscribe(Subscription s) {
}
@Override
public void onNext(BaseBean<List<Province>> listBaseBean) {
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
});
}
通过上面的代码我们不难看出这是经过封装后的效果,但是我们会发现这样的请求我们难道每次都要去添加调度器和重写Subscriber
的几个方法吗?那岂不还是很繁琐。是的,接下来我们就对这些进行封装。
使用compose操作符
public class SchedulersHelper implements FlowableTransformer{
@Override
public Publisher apply(Flowable upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
}
使用compose操作符可以直接对当前Flowable进行操作,所以我们自然可以把切换线程的操作加入这里。接下来就是Subscriber进行封装了。
封装Subscriber
public abstract class MySubscriber<T> implements Subscriber<T>{
@Override
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
showLoading();
}
@Override
public void onNext(T t) {
//code为1代表服务器返回成功的数据
if (((BaseBean)t).getCode() == 1) {
//成功后返回data数据进行处理即可
onSuccess((T) ((BaseBean) t).getData());
}else {
//处理服务器返回错误code
}
}
@Override
public void onComplete() {
finishLoading();
}
@Override
public void onError(Throwable t) {
finishLoading();
//处理网络异常
Log.d("TAG","=========" + t);
}
protected abstract void onSuccess(T t);
protected abstract void showLoading();
protected abstract void finishLoading();
}
如上所示,我们根据服务端返回的code判断是否成功,将data数据传出去。服务器返回的错误码和网络请求错误我们都可以统一在这里进行处理。然后我们再去测试接口。
测试
HttpRequest.getApi().province()
.compose(new SchedulersHelper())
.subscribe(new MySubscriber() {
@Override
protected void onSuccess(Object o) {
}
@Override
protected void showLoading() {
}
@Override
protected void finishLoading() {
}
});
可以的看到操作流程已经变的很简单了,对于showLoading()
和finishLoading()
这两个方法我们可以不需要放在这里面,这个是我方便测试便将其写在里面了。
结束
这是一个很简单封装过程,没有用到太多复杂的逻辑。比较通俗易懂,封装的完善度可能不是很高,大家可以当作一个参考,用自己的理解,更好的去封装它。之前有写过一篇简单的MVP基类,这个封装过程我便将它放在了上一篇的项目中。构成了一个简单易懂易上手的:RxJava + Retrofit + MVP的小Demo,放在了GitHub上,大家可以查看RxRetrofitMvp。如果你觉对你有帮助的话请,希望给个star哦,哈哈哈!
来源:https://blog.csdn.net/zl_china/article/details/79467558


猜你喜欢
- Java 17 更新了,作为一个 10 年的 Java 程序员,还是有亿点点兴奋的,Kotlin 的群里面也是各种讨论 Java 的新特性。
- 内存映射文件是利用虚拟内存把文件映射到进程的地址空间中去,在此之后进程操作文件,就像操作进程空间里的地址一样了,比如使用c语言的 memcp
- 需求:校验收货地址是否超出配送范围重要:做该需求的思路就是通过卖家和卖家具体的地址信息,来获取到二者的经纬度, 此时可以使用百度的 &quo
- 1. 概述官方JavaDocsApi: java.awt.Component,java.awt.Containernull,绝对布局。绝对布
- 在安全卫生上,经常看到有圆形的进度条在转动,效果非常好看,于是就尝试去实现一下,具体实现过程不多说了,直接上效果图,先炫耀下。效果图:分析:
- java 遍历listpackage com.tiandy.core.rest;import java.util.ArrayList;imp
- 有时候如果想让我们的应用在桌面上创建多个快捷方式,我们可以在Manifest.xml文件中对相应的activity进行声明。<appl
- 1.预警需求为了更好的管理商品日期,需要对仓库的商品进行预警管理,对商品的保质期控制在一个范围内提示出来,也可以通过该功能间接的展示出一个商
- 本节我们开始自我实现我们自己okhttp框架中的每个 * 。先简单回顾一下各个 * 的作用:RetryAndFollowUpIntercep
- 介绍装饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。就功能而言,装饰模式相比生成子类更为灵活,这样可以给某个对象
- 从今天开始写关于C#的系列文章,本篇文章主要讲解C#中的委托使用。委托其实就是一种数据类型,和int,string是一样的概念。如果要把一个
- 传输层安全性协议(英语:Transport Layer Security,缩写作 TLS),及其前身安全套接层(Secure Sockets
- 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序是基于插入排序的以下两点性质而提出改进方
- Eclipse Che被Eclipse官方称为下一代IDE,作为老牌的IDE,被其寄予厚望的Eclipse Che到底有什么特点,在这篇文章
- 我们在java中处理字符串的时候,一般会选择String,在python中同样也是作用于字符串。那么我们今天延伸一下它的用法,只使用Stri
- 这里以电视遥控器的一个例子来引出桥接模式解决的问题,首先,我们每个牌子的电视机都有一个遥控器,此时我们能想到的一个设计是——把遥控器做为一个
- 一、为什么会存在动态内存int data=20;//在栈空间上开辟4个字节空间char ch[5]={0};//在栈开辟5个字节连续空间上面
- 本文介绍了SharedPreferences保存应用程序数据的具体步骤,供大家参考,具体内容如下1、SharedPreferences的简单
- 一. * 搭建及配置1 . * 简介 * 是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件。有了 * 之后,当 Maven
- 本文实例讲述了Android7.0上某些PopuWindow出现显示位置不正确问题的解决方法。分享给大家供大家参考,具体如下:情景描述:在a