最近花了点时间了解学习了一下Retrofit库,现在记录一下。
一.What Retrofit是什么?有什么用?
Retrofit是一个Android下非常流行的网络请求库。
按照官方的介绍就是
A type-safe REST client for Android and Java
注意,Retrofit是一个基于==REST==的客户端请求库。
在学习Retrofit之前我们需要了解REST的概念,这也是使用这个库最大的难点,我大部分时间也都花在这个部分上。
那么,现在我们来介绍REST这个概念。
REST全称为Representation State Transfer,翻译过来就是表征状态转移。
它是一种特定的互联网架构,符合这种架构的软件,我们称它为==RESTful==
光看名字非常的抽象,但是我理解REST这个概念就是通过一个博客上对这个名字的解析。下面用我的语言重新来介绍一遍上面几个名词。
Representation
这个词是最不好理解的,要弄懂这个词的意思,首先我们要弄明白Resource的概念。
Resource,即资源,我们现在使用互联网其实就是在访问互联网上的一个个资源并组织使用它们。不管是客户端还是直接通过浏览器,我们要上网需要做的事情是什么?通过网络获取特定的信息并显示为符合我们要求的形式给我们阅读。
在这个过程中,首先通过URI(Uniform Resource Identifier)即唯一定位这个资源的标识符来访问这个资源,这个资源就是在服务器中存储的信息,它可以是图片、视频、任何东西,总之就是一些被保存在硬盘里的文件,我们在访问了它们之后,服务器按照规定的格式将这个文件返回给访问者,这样就完成了资源的调用。
那么Representation在这个过程中是什么样的一个概念呢?
在我们使用URI的过程中,我们并不指定这个资源的格式,因为URI仅仅代表这个文件的访问路径,而这个路径不应该包含这个资源它本身的格式和内容,因此Representation(表征)即指这个资源的表示形式。这种形式可以是JPG、JSON、XML、HTML、AVI。
State Transfer
通过上面的阅读,我们知道了在访问过程中我们使用URI仅仅只是得到了这个资源,那么将这个资源转换成Represtation的这个过程即为State Transfer(状态转换)。这个转换过程发生在服务器上,我们在客户端通过HTTP协议向服务器发送请求去控制这个过程,要求服务器返回我们希望的内容。
综上所诉
我直接引用我学习的博客中的总结,我认为非常的精炼。
综合上面的解释,我们总结一下什么是RESTful架构:
(1)每一个URI代表一种资源;
(2)客户端和服务器之间,传递这种资源的某种表现层;
(3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现”表现层状态转化”。
二.How Retrofit的使用
理解了REST的概念,接下来就可以学习Retrofit的具体使用了。
使用步骤
1.创建一个Retrofit实例
1 | public static final String BASE_URL = "http://api.myservice.com/"; |
可以看到,根据REST架构,首先我们确定我们所访问的Api的资源基本URI,这个URI是这一批接口的公共前缀。
我们要使用的具体的每一个Api都是BASE_URL/xxx/xxx这种形式。
接下来创建一个Retrofit实例,将这个BaseURL传入,并指定Retrofit解析这个资源使用的解析库,具体使用哪一个需要具体分析,这里不再叙述。
有如下的解析库可以选择:
Converter Library
Gson com.squareup.retrofit:converter-gson:2.0.0-beta2
Jackson com.squareup.retrofit:converter-jackson:2.0.0-beta1
Moshi com.squareup.retrofit:converter-moshi:2.0.0-beta1
Protobuf com.squareup.retrofit:converter-protobuf:2.0.0-beta1
Wire com.squareup.retrofit:converter-wire:2.0.0-beta1
Simple XML com.squareup.retrofit:converter-simplexml:2.0.0-beta1
这样,我们就创建了一个符合我们要求的retrofit实例了。
2.根据我们使用接口返回数据的格式创建对应的实体类
这里我推荐使用一款Android Studio插件GsonFormat,根据字符串一键生成对应的实体类。
3.创建对应的接口
1 | public interface ApiInterface{ |
定义一个Retrofit接口一共需要指定两样东西。
(1)指定HTTP的动作
我们可以选择的参数有四个,分别为:
GET
POST
PUT
DELETE
不清楚这几个动作在HTTP中的具体的含义的同学可以自行百度再仔细研究。
这里我推荐一篇文章:
http://286.iteye.com/blog/1420713
在后面的参数为BASE_URL后另加入的地址,从而指定我们要调用的Api的URL。
这里有一个坑!
BaseURL和@GET后的附加的URL的问题。
我使用的retrofit2.0在BaseURL后的URL必须以/结尾!!
也就是说
1 | http://api.myservice.com/ |
是不同的!这个/你不能接在@GET中的URL的附加中,retrofit对这一点有绝对的要求,如果你像后面一样,你就会成功接收到返回的数据,但是狂报404..请记住这点
(2)创建在Api调用完成后被回调的函数。
在Retrofit2.0之前这个回调函数是可以有两种定义模式的,分别为同步与异步,但是在2.0删除了同步的写法,目前只有一种异步的定义方式。
1 | Call<User> getUser(@Path("username") String username); |
Call的泛型中的类型即为完成调用后解析得到的实体类的类型。
在方法中同时可以使用特殊的注解。
这里有几种特殊的注解参数可以选择
@Path
使用@Path注解可以将URL中的变量替换为注定的值。
@Query
使用@Query注解可以提供查询参数,这个注解结合POST使用。
@Body
使用@Body注解可以将指定类型的对象直接发送到服务器。
剩下的注解可以在使用时再具体查询,我这里对我认为不太重要的注解不再介绍。
(3)执行我们创建的call。
如果想要在当前线程执行call。
1 call.execute();
一行代码即可。
如果想要在另外一个新线程中执行enqueue1
call.enqueue()
使用令call入队等待执行。
注意每一个Call仅能执行一次,如果想要再次执行这个Call,就必须再创建一个新的Call,官方当然给了我们解决方法。使用call.clone()即可复制一个完全一样的Call。
下面附上我项目中使用的一个完整的实例。
1 | Retrofit retrofit = new Retrofit.Builder() |
1 | public interface StartImageInterface { |
好了,Retrofit使用的基本介绍到这里就结束了。
##三.Why Retrofit实现的原理
这一块内容还是等我水平足够再仔细研究。。
##四.其它
如果要学习Retrofit,请在官方处下载当前最新的2.0,而且注意,2.0与之前的版本有较大差异,如果要查询相关的问题,请记得注意Retrofit的版本问题,有不少研究Retrofit的文章已经过时了。
使用Retrofit+Okhttp,完美解决网络调用问题。
注意,Retrofit只有在Api符合REST规范,即它是RESTful时,我们使用才足够的方便。如果碰上一些个别的奇葩Api,这个时候我们可以使用Okhttp来解决问题,Okhttp是Squre的另一个网络通讯库,而且Retrofit的底层也正是基于Okhttp实现的,可以说,Retrofit就是以Okhttp为骨架,封装了一些另外的功能,从而方便我们调用RESTful的专用库。因此Okhttp的用法与Retrofit几乎相同,我们使用时也不用考虑什么兼容问题,放心大胆的使用就可以了!
Retrofit官方网站
OkHttp官方网站
OkHttp
参考博客
Retrofit 2.0:有史以来最大的改进
理解RESTful架构