Retrofit2.0+RxAndroid
来源:互联网 发布:淘宝天下小二怎么联系 编辑:程序博客网 时间:2024/06/06 17:05
最近看了很多关于Retrofit和Rxjava的文档介绍。终于在弄清Rxjava后顺利的弄懂了Retrofit。
网上有很多人都介绍了它们的联合使用,但是我看过之后理解不是太好。可能我太笨。
不过,今天写这篇博客的目的就是想来说说它们之间如何使用以及使用的时候遇到的坑。
这两者的关系并不大,但是联合在一起使用是非常简便的。Rxjava的响应式编程加上Retrofit的注解式请求用起来是非常爽的。
并且Retrofit内置的是Okhttp,所以这更加的让Retrofit变得强大。
如果在看这篇博客的时候你对Java注解、Rxjava还有Okhttp还不够了解,建议先去了解这两个东西。
给出友情链接:
java 注解——使用详解
RxJava——响应式和区域化的优秀框架(java&android)
android http——OkHttp使用详解
相信看到这里,你已经对上面三个知识有了了解。
那么接下来切入正题。
先来加入依赖库:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
没错,你需要的库就是这么多。若要联合它们三者使用,就必须这么多。
我来按顺序介绍。
1,Rxjava库
2,RxAndroid库
3,Retrofit适配Rxjava的库
4,Retrofit库
5,Retrofit适配Gson的库(添加了这个库后不用再添加Gson库,因为已经内置)
另外还要有Okhttp依赖库。在Android sdk中已经内置。似乎Retrofit中也内置了Okhttp,所以我项目中没有加入okhttp依赖库,但是okhttp依旧可以使用。
这里需要说明一下,第五个依赖库根据你的项目需求来添加。
一般的项目来说都是使用json数据的。若你的项目是使用xml或者其他的数据格式,那么对应的添加。
(以下版本号需要与retrofit版本号保持一致,并且以retrofit官网给出的版本号为准。)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
好了。依赖库加完以后。我们就开始请求了。
我们先来个测试url
- 1
- 1
这个是阿里云根据地区名获取经纬度接口。
返回json数据
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
我们先来写好实体类AliAddrsBean和IndexRequestBean
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
Retrofit的请求管理类RetrofitManage(先写成单例)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
定义一个发送网络请求的方法sendRequest()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
Retrofit 实例化 注意事项:
1,每一个Call实例的用法和okhttp的call几乎一样。
2,call只能被使用一次,若再次调用会抛出异常。如果需要多次使用请使用clone
3,默认反序列化OkHttp的ResponseBody类型
4,默认只能接受ResponseBody类型的参数作为@body
5,2.0以后,get请求和post的请求的区别在call里面,注解写@get和写@post已经没有区别了
sendRequest()方法中已经写的很清楚了,不再多说。
承载一切请求的接口ApiService
这个类我要分开写,因为内容实在太多。
规则:每一个函数都必须有提供请求方式和相对URL的Http注解
Retrofit提供了5种内置的注解:GET、POST、PUT、DELETE和HEAD
注解中指定的资源是相对的URL
注解中指定的资源是相对的URL
注解中指定的资源是相对的URL
为啥说三遍,不解释。
这是第一个细节也是第一个门槛。
注解里到底写的是什么?
我们先来看看一个简单的、迷茫的get请求。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
url呢?
注解里写的啥?
query又是啥?
怎么调用?
怎么返回?
这是我在网上看到最多的示例。
我就搞不懂了,给一个初学者写这么一个东西谁看得懂?
所以,我来一步一步的解释清楚,写一个易懂的例子。
先来回顾一下我们的url:http://gc.ditu.aliyun.com/geocoding?a=上海市&aa=松江区&aaa=车墩镇
参照这个url我们来写一个get请求:
- 1
- 2
- 1
- 2
这么看就明白了吧,注解中就是一个url而已。
看看怎么调用的
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这就是最简单粗暴的调用方法。这里需要注意的是,我们还需要传入一个实体类作为返回数据的解析依据。
这里我们就是传入的AliAddrsBean。Retrofit已经帮我们把数据解析好了。
可以看出来我们在外面调用了.baseUrl(url) ,为什么在注解中还需要写url呢?
这就关系到很多的细节和坑了。
现在我们假定我们的url是这样的:http://gc.ditu.aliyun.com/geocoding?
如果我们在注解里面这么写:
(以下有坑)
- 1
- 2
- 1
- 2
看似是对的,其实在我做demo的时候用okhttp请求成功但是用retrofit请求一直失败。
究其原因就是:注解中必须要有一部分的url地址,不能光是请求体。
所以,修改代码:
请求url:http://gc.ditu.aliyun.com/
以下是正解:
- 1
- 2
- 1
- 2
这么一写,果然请求正常了。
另外还有一个坑,Retrofit建议url以/结束,注解不要以/开始
我们将get请求汇入接口ApiService中:
基本get请求
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
{ }取代块和@Path
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
所以,取代块只能取代url,不能取代参数,且@path的作用就是专职于取代块
调用的时候把参数传进来
- 1
- 1
@Query 键值对传参
看到那么多参数请求,肯定有简单的方法,单个参数添加
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
调用:
- 1
- 1
@query的作用就相当于拼接字符串:a=上海市&aa=松江区&aaa=车墩镇
@QueryMap 参数集合
有时候我们参数很多,一个一个的用@query去传肯定不方便。
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
调用:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
@Body 请求体
我们可以把参数封装成一个实体类,然后传过去。这么做比map传参更加方便。
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
调用
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
这种做法得到的结果一样,但是方便了许多。
@FormUrlEncoded 和@Field 发送表单数据
@FormUrlEncoded注解的时候,将会发送form-encoded数据
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
调用:
- 1
- 1
@Multipart和@Part 发送字节流数据
我们有时候要在发送请求前规定数据的编码格式,那么我们就可以用这个注解来解决。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
可能这样看不太懂,那么我们就看看如何调用的就懂了
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
当然,既然是requestbody类型,我们就可以用它来穿文件了。
- 1
- 2
- 1
- 2
@Headers给函数设置header
对于给一个请求设置header我在日志中看到打印了header的内容。
如果我们每次都要给服务器一些固定参数,,例如版本号,请求接口版本,key等。我们就可以用它来设置在http请求的头里。
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
调用和get请求没有区别。是不是很方便?
@Header 单个参数的header
我感觉这个没什么卵用。。。
不过还是贴出来使用方法
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
适配Rxjava
这么多的Retrofit都是返回的call,我们应该如何适配Rxjava呢?
Retrofit默认是可以适配Rxjava的。
所以我们要做的就是:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
调用:
- 1
- 1
我们得到了带有网络请求数据的Observable对象后我们就可以依照Rxjava来做一系列的响应式编程了。
这里还有一个坑,先看我们如何处理数据
(以下有坑)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
我们直接给观察者或者叫订阅者发送消息“嘿!网络请求的数据回来了!”
这样做看似没问题,但是在我实际运行中却报错了。
异常表示数据处理需要在非ui线程。
那么就很了然了。我们得到requestInde的对象后要在非ui线程中操作。
以下代码已经填坑
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
我们要变换线程,处理数据的时候开一个新线程。返回结果就应该在主线程了。这里写android的ui线程就是用到的Rxandroid中的方法。
Observable.zip打包多个网络请求
有时候我们需要边加载数据边下载某个图片或者音乐甚至是各种文件。那么这个时候我们就要把多个网络请求打包起来一起发出去了。
那么这个时候我们就要借助Observable.zip这个操作符了。
先来看如何实现的
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
我们看zip这个操作符的源码可以得知,它能够封装两个被订阅者(Observable)对象。
并且默认还需要实现一个得到这两个Observable对象中的数据后的二次处理方法(Func2),把这两个对象的结果处理成一个然后发送给观察者(subscribe)。
一开始,并不知道哪个参数对应哪个,看了源码后才搞清楚。方法中我在注释中已经写的很清楚了。
这样我们就把两个网路请求同时进行,然后返回的结果处理成一个拿出来。达到了打包多个网络请求的目的。
添加okhttp委托
因为Retrofit内置okhttp,所以我们也可以为它设置一个委托okhttp对象。
具体委托方式:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
那么这个委托我们能做什么呢?
这里我写了一个okhttp的拦截器
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
我们可以做一个okhttp的拦截器,可以打印日志,可以clone 。反正发挥自己的想象,为正在请求的事件做一些额外的事情。
总结
写到这里,这个强强联合的框架已经写完了。
其实我们可以感觉到,这个框架主要是Retrofit2.0+RxJava+RxAndroid+OkHttp
其中RxAndroid的目的可能就是在android中使用的时候让网络请求回到主线程。
而Retrofit2.0+RxJava+OkHttp则充分的让这个网络请求框架变得如此之简单、之响应式、之模块化。
我们用注解去发送请求,简单、简洁;用Rxjava来让代码块状化,逻辑更清晰;网络请求有okhttp作为强大的后台可以很好的完成各种请求。
其中还有很多没有讲到的,比如Rxjava的RxBus和RxBinding方面。okhttp的更多操作。
因为Retrofit和okhttp一样,不支持下载进度的回调。所以之类附上另一位同行的博客来解决这个问题,顺便自己也学习学习。
解决Retrofit文件下载进度显示问题
- Retrofit2.0+RxAndroid
- Retrofit2.0+RxAndroid+RxBus
- rxjava+rxandroid+retrofit2.0使用方法demo讲解
- Retrofit2+RxAndroid 详解
- rxAndroid+OkHttp+retrofit2三贱客
- Rxjava2+retrofit2+rxAndroid+okHttp
- Retrofit2、okHttp3、RxAndroid使用
- Kotlin入门 + RxAndroid+Retrofit2
- MVP实战心得(三)---封装Retrofit2.0+RxAndroid+RxBus
- android架构封装(mvp + rxandroid + Retrofit2.0 )
- MVP实战心得(三)---封装Retrofit2.0+RxAndroid+RxBus
- MVP实战心得(三)---封装Retrofit2.0+RxAndroid+RxBus
- Retrofit2.0+RxJava+RxAndroid——强强联合的网络请求框架
- 基于ijkplayer+Rxjava+Rxandroid+Retrofit2.0+MVP+Material Design的android万能播放器
- Retrofit2.0+RxJava+RxAndroid——强强联合的网络请求框架
- Retrofit2.0+RxJava+RxAndroid——强强联合的网络请求框架
- rxandroid结合retrofit2发送post请求
- Retrofit2.0
- ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password :Y)
- PostgreSQL之Json类型使用
- malloc能分配多大内存
- CentOS 6 yum安装Maven
- js判断是否为空
- Retrofit2.0+RxAndroid
- spring的BeanUtils.copyProperties用法
- ibtais中的isNotNull、isEqual、isEmpty
- 用百度siteapp的uaredirect.js判断用户访问端而进行域名的自动跳转,并通过cookie记录手机访问电脑端的状态
- ZOJ3787-Access System
- eclipse Java Web项目自定义访问项目名称
- [转载]最佳实践之Android代码规范
- 利用 force index优化sql语句性能
- Mysql-存储过程