深入解析开源项目之Retrofit(一)使用篇
2015-12-17 17:19
579 查看
珍惜作者劳动成果,如需转载,请注明出处。
http://blog.csdn.net/zhengzechuan91/article/details/50337883
Retrofit(Github地址)是square公司一套开源的http框架,简单易用,并且支持okhttp和RxJava,如果你不想为配置繁杂的http请求而写一套自己的网络请求框架,那么这套优雅的框架你不妨试试。
首先生成RestAdapter代理的接口RealService
然后在接口RealService中定义:
同步
如果是上面这种没有callback的同步方式,则需注意在非UI线程中调用。
异步
而如果参数中有callback的话,则可以直接在UI线程中调用,而返回值会通过callback返回。
这样我们我获取到了API返回的数据,然后再根据这些数据做一些别的处理,使用是不是很简单呢?
上面我们看到参数、Url和请求方式都是通过注解的方式设置的,非常简单方便。
POST
HEAD
PATCH
PUT
FormUrlEncoded
Headers
Multipart
EncodedPath
EncodedQuery
EncodedQueryMap
Path
Query
QueryMap
Field
FieldMap
Header
Part
1.post请求:使用@Body标记参数
2.get请求:如果参数为为非Map类型,使用@Query标记参数
如果参数类型为Map类型,使用@QueryMap标记参数
3.上传文件/图片请求:使@Part标记参数
4.表单类型:如果参数类型为非Map类型,使用@Field标记参数
如果参数类型为Map类型,使用@FieldMap标记参数
5.如果方法的@GET或@POST中有占位符,使用@Path标记参数
基本常用的就这么多。
我们发现这个回调返回的是一个RequestFacade类型的,我们看看
RequestFacade接口是怎么定义的:
这个接口定义了向head、path、query中添加参数的接口,并且可以通过getMethodInfo()得到方法的注解信息。
我们看看TypedInput:
TypedInput给我们返回了mime类型、数据长度和输入流供我们解析。
而TypedOutput则是给我们提供向服务器发送数据的输出流,我们将对象的(Json)字符串写入到输出流中。
而我们自定义Converter时,只需处理POJO和标准的TypedInput、TypedOutput的转换操作即可:
以上就是我们平常会在项目中用到的retrofit的全部内容,是不是很简单呢?使用简单,意味着框架为我们做了很多事情。下一篇博客我们将主要介绍retrofit的实现原理。
http://blog.csdn.net/zhengzechuan91/article/details/50337883
Retrofit(Github地址)是square公司一套开源的http框架,简单易用,并且支持okhttp和RxJava,如果你不想为配置繁杂的http请求而写一套自己的网络请求框架,那么这套优雅的框架你不妨试试。
使用
先来说说这个框架的使用:首先生成RestAdapter代理的接口RealService
RestAdapter adapter = new RestAdapter.Builder() .setClient() .setEndpoint() .setRequestInterceptor() .setConverter() .setLogLevel(LogLevel.FULL) .build(); RealService real = adapter.create(RealService.class);
然后在接口RealService中定义:
同步
public interface RealService { @GET("/info/") String getString(@Query("id") String id) }
如果是上面这种没有callback的同步方式,则需注意在非UI线程中调用。
String id = "1"; String info = real.getString(id);
异步
public interface RealService { @GET("/info") void getString(@Query("id") String id, Callback<String> callback) }
而如果参数中有callback的话,则可以直接在UI线程中调用,而返回值会通过callback返回。
String id = "1"; Callback<String> callback = new Callback() { void success(String var1, Response var2); void failure(RetrofitError var1); } real.getString(id, callback);
这样我们我获取到了API返回的数据,然后再根据这些数据做一些别的处理,使用是不是很简单呢?
上面我们看到参数、Url和请求方式都是通过注解的方式设置的,非常简单方便。
注解
首先来看一些注解的定义,这个在我们添加参数时还是很重要的:作用于注解的注解
RestMethod@Documented //这个注解是用于注解上面的 @Target({ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface RestMethod { //请求方式 String value(); //是否有body boolean hasBody() default false; }
作用于方法的注解
GET@Documented //这个注解是用于方法上的 @Target(METHOD) @Retention(RUNTIME) @RestMethod("GET") public @interface GET { //get请求方式,无body String value(); }
POST
@Documented //这个注解是用于方法上的 @Target(METHOD) @Retention(RUNTIME) @RestMethod(value = "POST", hasBody = true) public @interface POST { //post请求方式,有body String value(); }
HEAD
@Documented //这个注解是用于方法上的 @Target(METHOD) @Retention(RUNTIME) @RestMethod("HEAD") public @interface HEAD { //head请求,无body String value(); }
PATCH
@Documented //这个注解是用于方法上的 @Target(METHOD) @Retention(RUNTIME) @RestMethod(value = "PATCH", hasBody = true) public @interface PATCH { //patch请求,有body String value(); }
PUT
@Documented //这个注解是用于方法上的 @Target(METHOD) @Retention(RUNTIME) @RestMethod(value = "PUT", hasBody = true) public @interface PUT { //put请求,有body String value(); }
FormUrlEncoded
@Documented //这个注解是用于方法上的 @Target(METHOD) @Retention(RUNTIME) public @interface FormUrlEncoded { //表单类型,参数使用@Field注解,application/x-www-form- //urlencoded有值,并且在URI-decode前先会转为UTF-8 }
Headers
@Documented //这个注解是用于方法上的 @Target(METHOD) @Retention(RUNTIME) public @interface Headers { //head中添加参数 String[] value(); }
Multipart
@Documented //这个注解是用于方法上的 @Target(METHOD) d980 @Retention(RUNTIME) public @interface Multipart { //参数类型需为@Part注解 }
作用于参数的注解
Body@Documented //这个注解是用于参数中的 @Target(PARAMETER) @Retention(RUNTIME) public @interface Body { //post/put方式参数标记 //如果参数被用@Body注解,则分为以下两种情况: //1.这个参数实现了TypedOutput,则body会被重写为 //TypedOutput#writeTo(); //2.这个参数没有实现TypedOutput,则body会被RestAdapter //的Converter序列化(serialized) }
EncodedPath
@Documented @Retention(RUNTIME) //这个注解是用于参数中的 @Target(PARAMETER) public @interface EncodedPath { //这个注解标注的变量可以替换Path中的占位符, //但不参与uri的decode,例如: //@GET("/image/{id}") //void example(@EncodedPath("id") int id, ..); String value(); }
EncodedQuery
@Documented //这个注解是用于参数中的 @Target(PARAMETER) @Retention(RUNTIME) public @interface EncodedQuery { //这个注解标注get请求单个参数, //但不参与uri的decode String value(); }
EncodedQueryMap
@Documented //这个注解是用于参数中的 @Target(PARAMETER) @Retention(RUNTIME) public @interface EncodedQueryMap { //这个注解标注get请求Map参数, //但不参与uri的decode }
Path
@Documented @Retention(RUNTIME) //这个注解是用于参数中的 @Target(PARAMETER) public @interface Path { //这个注解标注的变量可以替换Path中的占位符 //参与uri的decode String value(); }
Query
@Documented //这个注解是用于参数中的 @Target(PARAMETER) @Retention(RUNTIME) public @interface Query { //这个注解标注get请求单个参数, //参与uri的decode String value(); }
QueryMap
@Documented //这个注解是用于参数中的 @Target(PARAMETER) @Retention(RUNTIME) public @interface QueryMap { //这个注解标注get请求Map参数, //参与uri的decode }
Field
@Documented //这个注解是用于参数中的 @Target(PARAMETER) @Retention(RUNTIME) public @interface Field { //标记表单类型,参数为单个变量 String value(); }
FieldMap
@Documented //这个注解是用于参数中的 @Target(PARAMETER) @Retention(RUNTIME) public @interface FieldMap { //标记表单类型,参数为Map类型 }
Header
@Documented @Retention(RUNTIME) //这个注解是用于参数中的 @Target(PARAMETER) public @interface Header { //注解方式往head中添加参数 String value(); }
Part
@Documented //这个注解是用于参数中的 @Target(PARAMETER) @Retention(RUNTIME) public @interface Part { //Multipart的参数类型 //注解标记的变量分为以下3种情况: //1.实现TypedOutput借口,直接使用 //2.String类型,直接使用 //3.其他类型会调用Converter#toBody()转换 String value(); }
Android参数注解选择
上面对用到的注解做了详细的介绍,总结下Android下注解的选择:1.post请求:使用@Body标记参数
2.get请求:如果参数为为非Map类型,使用@Query标记参数
如果参数类型为Map类型,使用@QueryMap标记参数
3.上传文件/图片请求:使@Part标记参数
4.表单类型:如果参数类型为非Map类型,使用@Field标记参数
如果参数类型为Map类型,使用@FieldMap标记参数
5.如果方法的@GET或@POST中有占位符,使用@Path标记参数
基本常用的就这么多。
拦截器
我们在构造RestAdapter时,是可以设置自定义的拦截器,只需要实现RequestInterceptor接口。通过拦截器我们可以在请求Api之前向head、path、query中添加参数,来满足我们对一些公共参数的添加。public class MyInterceptor implements RequestInterceptor { @Override public void intercept(RequestFacade request) { //这里通过request往head、path、query中添加额外参数 request.addHeader("key1", "value1"); request.addPathParam("key2", "value2"); request.addQueryParam("key3", "value3"); } }
我们发现这个回调返回的是一个RequestFacade类型的,我们看看
RequestFacade接口是怎么定义的:
public interface RequestFacade { void addHeader(String var1, String var2); void addPathParam(String var1, String var2); void addEncodedPathParam(String var1, String var2); void addQueryParam(String var1, String var2); void addEncodedQueryParam(String var1, String var2); RestMethodInfo getMethodInfo(); }
这个接口定义了向head、path、query中添加参数的接口,并且可以通过getMethodInfo()得到方法的注解信息。
Converter
框架默认实现的是到Gson的转换,如果我们的数据是别的Json解析方式或是xml解析方式,我们就需要自定义converter,先看下Converter接口的定义:public interface Converter { //从服务器读取数据(将输入流解析成POJO) Object fromBody(TypedInput body, Type type) throws ConversionException; //向服务器发送数据(将POJO的字符串转换成流,写入输出流) TypedOutput toBody(Object object); }
我们看看TypedInput:
public interface TypedInput { String mimeType(); long length(); InputStream in(); }
TypedInput给我们返回了mime类型、数据长度和输入流供我们解析。
public interface TypedOutput { String fileName(); String mimeType(); long length(); void writeTo(OutputStream var1) throws IOException; }
而TypedOutput则是给我们提供向服务器发送数据的输出流,我们将对象的(Json)字符串写入到输出流中。
而我们自定义Converter时,只需处理POJO和标准的TypedInput、TypedOutput的转换操作即可:
public class MyConverter implements Converter { Object fromBody(TypedInput body, Type type) { //从服务器读取数据(将输入流解析成POJO) } TypedOutput toBody(Object object) { //向服务器发送数据(将POJO的字符串转换成流, //写入输出流) } }
以上就是我们平常会在项目中用到的retrofit的全部内容,是不是很简单呢?使用简单,意味着框架为我们做了很多事情。下一篇博客我们将主要介绍retrofit的实现原理。
相关文章推荐
- 查看github pages文档的方式
- 使用BAE的基于Web.py的简单博客程序
- Ruby微信开发的几个开源项目介绍
- 两分钟学会如何在github托管代码
- 利用AJAX开源项目 在网页里播放视频实现方法
- 使用PHP把HTML生成PDF文件的几个开源项目介绍
- github配置使用指南
- github版本库使用详细图文教程(命令行及图形界面版)
- python使用心得之获得github代码库列表
- C语言实现的轻量级brainfuck语言解释器
- My Machine Learning
- 机器学习---学习首页 3ff0
- nice-repo 搜集优秀的开源项目
- 利用GitHook构建持续交付和部署
- Android projects on Github
- 跟我一起看Retrofit 2.0的源码
- git 提交步骤记录(oschina&github)