Retrofit是Square公司开发的一个类型安全的Java和Android 的REST客户端库,这个库为网络认证、API请求以及用OkHttp发送网络请求提供了强大的框架 。Retrofit 库使得从web api下载JSON 或者xml数据变的很是简单直接,一旦数据下载完成即将其解析成普通java类(POJO)。
Retrofit支持Java 7 或 Android 2.3及以上版本。java
注:Rest API是一种软件设计风格,服务器做为资源存放地。客户端去请求GET,PUT, POST,DELETE资源。而且是无状态的,没有session的参与。git
Retrofit使用的最核心的两个技术:动态代理和Java反射。Retrofit很是巧妙的用注解来描述一个HTTP请求,将一个HTTP请求抽象成一个Java接口,而后用了Java动态代理的方式,动态的将这个接口的注解“翻译”成一个HTTP请求,最后再执行这个HTTP请求。github
Retrofit无非就是让用户建立接口,并在接口中指定网络访问路径、规则,把接口传入Retrofit,Retrofit进行层层解析,而后调用OkHttp完成实际的网络请求并将请求结果处理后返回给用户。web
底层使用OkHttp进行网络传输,性能好,速度快;json
拥有出色的API文档和社区支持api
能够自动将REST API返回的数据转化为Java对象,且支持多种数据转换格式(如json、xml等)浏览器
使用Java注解声明HTTP请求安全
支持 Multipart请求和文件上传服务器
下面经过一个实际的例子介绍Retrofit的使用流程。该示例程序经过使用Retrofit向https://api.github.com/ 获取指定github用户的相关信息。目前Retrofit的最新版本为2.0版,与此前的1.9有比较大的不一样,该示例代码是基于Retrofit2.0实现的。网络
注:在浏览器输入网址https://api.github.com/users/"想要查询的github用户名",服务器便会返回一个包含该用户信息的json字符串,如输入https://api.github.com/users/littleshuang ,所获得的json字符串为
第一步:添加依赖(gradle)
//retrofit底层网络框架为OkHttp,因此必须添加OkHttp的依赖包 compile 'com.squareup.okhttp3:okhttp:3.2.0' //retrofit的依赖包 compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4' //添加了一个官方提供的json conventer compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
第二步:构建返回数据对应的实体类
注:Retrofit能够自动根据咱们提供的conventer将返回数据转化为JOPO,因此咱们须要建立一个返回数据的实体类
本实例中根据前述json数据格式建立了一个User类
第三步:定义一个请求数据的接口,该接口中包含用于请求数据的方法定义(此例中定义了一个名为ServiceInterface的接口,其中包含一个获取用户信息的get请求)
@GET:retrofit提供的一个用于定义请求方法的注解,retrofit会根据该注解将该方法解析为一个相应请求类型的http请求
users/{user}:http请求的相对路径,该路径为相对于自定义的BaseURL的路径,该示例中的BaseURL为:https://api.github.com/ ;大括号包裹的{user}是retrofit提供的一种动态生成URL地址的方式,大括号中包含的内容的具体类型和数据须要经过注解@Path后面的参数得到,此例中为一个String类型变量,具体值由user变量提供
注:此处也可使用绝对路径,但通常来讲,同一项目中的绝大部分网络请求都是基于同一服务器基址,变化的只是后面的相对路径,因此推荐使用BaseURL + 相对路径的方式,这种方式既能减小没必要要的冗余代码,使代码更加简洁,又能减小出错几率、提升重构效率。
Call<T>:retrofit中定义的一个接口,该接口中主要定义了同步请求(execute)、异步请求(enqueue)、取消请求(cancle)等方法,该接口的实现类经过实现这些方法执行具体的网络请求操做;虽然Retrofit默认使用OkHttp执行具体的网络请求操做,可是,咱们能够经过本身实现该接口而采用本身的逻辑来执行网络请求,这种方式很是插件化,从而很是灵活
第四步:使用Retrofit对象执行网络请求
// 获取一个Retrofit对象,并设置该对象的BaseURL和conventer Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com/") .addConverterFactory(GsonConverterFactory.create()) .build(); // service其实是create方法返回的一个ServiceInterface接口的动态代理 ServiceInterface service = retrofit.create(ServiceInterface.class); // 经过下面这个语句就建立了一个向获取数据的get请求 Call<User> call = service.getUser("littleshuang"); // enqueue是一个异步请求方法 call.enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { if (response.isSuccess()){ // isSuccess()函数的处理逻辑很是简单,只是判断了下response的返回码是否为200,是即true,不然false // 因此能够本身根据本身的须要进行处理 User user = response.body(); if (user != null){ etRetrofitGetUser.setText("User login: " + user.getLogin()); } } } @Override public void onFailure(Call<User> call, Throwable t) { etRetrofitGetUser.setText("Sth wrong!"); } });
结果展现:左右两图分别展现的是网络请求成功和失败两种状况下的结果
Retrofit源码下面的http包中包含了Retrofit中定义的所有22中注解类型,这些注解都是用于控制HTTP请求的一些接口方法,下面对这些注解进行简单的介绍,便于之后的使用
请求方法类:@GET @HEAD @POST @DELETE @PUT @OPTIONS @PATCH,这几个注解分别表示定义一个get、head、post、delete、put、options或patch请求;
HTTP请求体:@BODY,该注解适用于在使用post或put请求时想要直接控制HTTP请求体的状况,此注解参数不能为空;
定义一个表单形式的请求:@FormUrlEncoded及@Field(或@FieldMap),该注解适用于须要使用表单形式提交一个名值对的表单数据的情形,@FormUrlEncoded声明该请求的请求体为表单形式,@Field定义请求体中的一组名值对,而@FieldMap定义多个名值对的组合
For example:
@FormUrlEncoded @POST("users/{user}") User updateUser(@Field("id") int id, @Field("name") String name); @FormUrlEncoded @POST("users/") Call<User> add(@FieldMap Map<String, String> fields);
使用 service.updateUser(1, "Bob")时,请求体为id=1&name=Bob
使用service.add("name", "Bob", "nickname", "LittleBob")时,请求体为name=Bob&nickname=LittleBob
HTTP请求头:@HEADER 和@HEADERS,注意这二者的区别,二者都可以用于定义请求头部信息,可是前者会覆盖以前定义的头部信息,然后者不会,只会在后面进行追加;因此当屡次对同一名称的头域进行赋值时,使用前者只会保留最后一次的赋值,即一个头域至多只有一个赋值,而使用后者则会保留全部的赋值,即一个头域对应多个取值;
自定义HTTP请求客户端:@HTTP
定义一个Multi-part类型的请求:@Multipart和@Part(或@PartMap),该注解适用于请求体为Multi-part类型的请求,@Multipart声明一个Multi-part类型的请求,@Part定义一个Multi-part类型请求的一个单一部分,@PartMap定义一个一个Multi-part类型请求的名值对,用法相似于表单形式的请求的用法,就不详细介绍了
@Path:该注解后面的参数用于替换url中{}包含的部份内容
查询参数:@Query和@QueryMap分别定义一个查询参数和一个查询参数键值对
@Streaming:定义该注解表示将请求方法的返回值直接以流的形式返回,而不解析为Java实体类
@Url:该Url是一个相对于BaseURL的一个路径,定义该参数就表示该请求方法的相对地址为参数后面的内容
Retrofit和OkHttp同属于Square公司的开源项目,这二者是互补的关系,OkHttp是一个实现了HTTP协议的客户端,相似于HttpClient,而Retrofit是一个基于OkHttp的封装库,该库主要简化了http请求的实现过程,使得开发者只需关注自身功能的实现,而没必要书写那些比较冗余的代码。但也正是因为Retrofit的高度封装性,其扩展性就相对比较弱,某些比较灵活的功能还须要开发者本身经过OkHttp来实现。
Retrofit和Volley二者均是目前比较受开发者喜欢的两个网络库,不过这二者仍是有比较大的差别。
Retrofit的底层实现是OkHttp,Volley的底层实现的是HttpClient和HttpUrlConnection;
Retrofit的返回能够自动解析为Java实体类,而Volley的返回数据类型根据请求类型而定(StringRequeset、ImageRequest、JsonObjectRequest或JsonArrayRequest),同时须要本身进行解析;
Retrofit拥有比较详细的API文档和比较活跃的社区支持,而google貌似并未给Volley提供开发文档,只是在Android developers中的网络部分有所说起,因此在易用性方面,感受Retrofit更胜一筹;
Retrofit支持动态生成URL,Volley好像并不支持;
二者均异步请求方式,这在Android应用中是很是重要的,由于Android程序中不容许在Home线程中执行网络操做;