Retrofit使用大全

来源:互联网 发布:修改数据库system密码 编辑:程序博客网 时间:2024/06/03 17:20

珍惜作者劳动成果,如需转载,请注明出处。 
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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

然后在接口RealService中定义:

  • 同步
public interface RealService {    @GET("/info/")    String getString(@Query("id") String id)}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

如果是上面这种没有callback的同步方式,则需注意在非UI线程中调用。

String id = "1";String info = real.getString(id);
  • 1
  • 2
  • 1
  • 2
  • 异步
public interface RealService {    @GET("/info")    void getString(@Query("id") String id,         Callback<String> callback)}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

而如果参数中有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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这样我们我获取到了API返回的数据,然后再根据这些数据做一些别的处理,使用是不是很简单呢?

上面我们看到参数、Url和请求方式都是通过注解的方式设置的,非常简单方便。

注解

首先来看一些注解的定义,这个在我们添加参数时还是很重要的:

作用于注解的注解

  • RestMethod
@Documented//这个注解是用于注解上面的@Target({ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME)public @interface RestMethod {    //请求方式    String value();    //是否有body    boolean hasBody() default false;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

作用于方法的注解

  • GET
@Documented//这个注解是用于方法上的@Target(METHOD)@Retention(RUNTIME)@RestMethod("GET")public @interface GET {  //get请求方式,无body  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • POST
@Documented//这个注解是用于方法上的@Target(METHOD)@Retention(RUNTIME)@RestMethod(value = "POST", hasBody = true)public @interface POST { //post请求方式,有body  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • HEAD
@Documented//这个注解是用于方法上的@Target(METHOD)@Retention(RUNTIME)@RestMethod("HEAD")public @interface HEAD {  //head请求,无body  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • PATCH
@Documented//这个注解是用于方法上的@Target(METHOD)@Retention(RUNTIME)@RestMethod(value = "PATCH", hasBody = true)public @interface PATCH {  //patch请求,有body  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • PUT
@Documented//这个注解是用于方法上的@Target(METHOD)@Retention(RUNTIME)@RestMethod(value = "PUT", hasBody = true)public @interface PUT {  //put请求,有body  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • FormUrlEncoded
@Documented//这个注解是用于方法上的@Target(METHOD)@Retention(RUNTIME)public @interface FormUrlEncoded {    //表单类型,参数使用@Field注解,application/x-www-form-    //urlencoded有值,并且在URI-decode前先会转为UTF-8}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • Headers
@Documented//这个注解是用于方法上的@Target(METHOD)@Retention(RUNTIME)public @interface Headers {  //head中添加参数  String[] value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • Multipart
@Documented//这个注解是用于方法上的@Target(METHOD)@Retention(RUNTIME)public @interface Multipart {    //参数类型需为@Part注解}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

作用于参数的注解

  • Body
@Documented//这个注解是用于参数中的@Target(PARAMETER)@Retention(RUNTIME)public @interface Body {    //post/put方式参数标记    //如果参数被用@Body注解,则分为以下两种情况:    //1.这个参数实现了TypedOutput,则body会被重写为    //TypedOutput#writeTo();    //2.这个参数没有实现TypedOutput,则body会被RestAdapter    //的Converter序列化(serialized)}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • EncodedPath
@Documented@Retention(RUNTIME)//这个注解是用于参数中的@Target(PARAMETER)public @interface EncodedPath {  //这个注解标注的变量可以替换Path中的占位符,  //但不参与uri的decode,例如:  //@GET("/image/{id}")  //void example(@EncodedPath("id") int id, ..);  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • EncodedQuery
@Documented//这个注解是用于参数中的@Target(PARAMETER)@Retention(RUNTIME)public @interface EncodedQuery {  //这个注解标注get请求单个参数,  //但不参与uri的decode  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • EncodedQueryMap
@Documented//这个注解是用于参数中的@Target(PARAMETER)@Retention(RUNTIME)public @interface EncodedQueryMap {  //这个注解标注get请求Map参数,  //但不参与uri的decode}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • Path
@Documented@Retention(RUNTIME)//这个注解是用于参数中的@Target(PARAMETER)public @interface Path {  //这个注解标注的变量可以替换Path中的占位符  //参与uri的decode  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • Query
@Documented//这个注解是用于参数中的@Target(PARAMETER)@Retention(RUNTIME)public @interface Query {  //这个注解标注get请求单个参数,  //参与uri的decode  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • QueryMap
@Documented//这个注解是用于参数中的@Target(PARAMETER)@Retention(RUNTIME)public @interface QueryMap {  //这个注解标注get请求Map参数,  //参与uri的decode}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • Field
@Documented//这个注解是用于参数中的@Target(PARAMETER)@Retention(RUNTIME)public @interface Field {  //标记表单类型,参数为单个变量  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • FieldMap
@Documented//这个注解是用于参数中的@Target(PARAMETER)@Retention(RUNTIME)public @interface FieldMap {  //标记表单类型,参数为Map类型}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • Header
@Documented@Retention(RUNTIME)//这个注解是用于参数中的@Target(PARAMETER)public @interface Header {  //注解方式往head中添加参数  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • Part
@Documented//这个注解是用于参数中的@Target(PARAMETER)@Retention(RUNTIME)public @interface Part {  //Multipart的参数类型  //注解标记的变量分为以下3种情况:  //1.实现TypedOutput借口,直接使用  //2.String类型,直接使用  //3.其他类型会调用Converter#toBody()转换  String value();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

我们发现这个回调返回的是一个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();}
  • 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

这个接口定义了向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);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

我们看看TypedInput:

public interface TypedInput {    String mimeType();    long length();    InputStream in();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

TypedInput给我们返回了mime类型、数据长度和输入流供我们解析。

public interface TypedOutput {    String fileName();    String mimeType();    long length();    void writeTo(OutputStream var1) throws IOException;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

而TypedOutput则是给我们提供向服务器发送数据的输出流,我们将对象的(Json)字符串写入到输出流中。

而我们自定义Converter时,只需处理POJO和标准的TypedInput、TypedOutput的转换操作即可:

public class MyConverter implements Converter {    Object fromBody(TypedInput body, Type type) {        //从服务器读取数据(将输入流解析成POJO)    }    TypedOutput toBody(Object object) {        //向服务器发送数据(将POJO的字符串转换成流,        //写入输出流)    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

以上就是我们平常会在项目中用到的retrofit的全部内容,是不是很简单呢?使用简单,意味着框架为我们做了很多事情。下一篇博客我们将主要介绍retrofit的实现原理。

原创粉丝点击