转载请注明本文出自maplejaw的博客(http://blog.csdn.net/maplejaw_)
开源库地址:https://github.com/square/retrofit
解读版本:2.1.0
基本概念
Retrofit 是一个针对Java/Android类型安全的Http请求客户端。
基本使用如下:
首先定义一个接口,抽象方法的返回值必须为
Call<XX>
。public interface GitHubService { @GET("users/{user}/repos") Call<List<Repo>> listRepos(@Path("user") String user);//默认CallAdapter返回值必须为`Call<XX>`。 }
通过Retrofit的
create
创建接口实现//初始化Retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com/") //必须以斜杠结尾 .addConverterFactory(GsonConverterFactory.create())//添加Gson转换工厂 .build(); //通过Retrofit创建接口实现 GitHubService service = retrofit.create(GitHubService.class);
接口调用相关方法获取
Call<XX>
,然后就能和Okhttp一样进行同步/异步调用。Call<List<Repo>> repos = service.listRepos("octocat"); //异步调用 repos.enqueue(new Callback<List<Repo>>() { @Override public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) { List<String> list=response.body();//调用body() } @Override public void onFailure(Call<List<Repo>> call, Throwable t) { } }); //同步调用 Response<List<Repo>> response=repos.execute();
源码解读
Retrofit中的相关注解
请求方法注解
该类注解用于指明请求方法,在使用时必须指定且只可指定一种请求方法。
@GET
用来指明请求方法和相对/绝对/完整路径。当然也可以配合@Url使用。public interface RequestService { @GET("xx/xxx") //指定相对路径 Call<ResponseBody> getContent1(); @GET("/xxx") //指定绝对路径,相对路径和绝对路径的区别见后文 Call<ResponseBody> getContent1(); @GET("http://www.baidu.com") //指定完整Url Call<ResponseBody> getContent2(); @GET //配合@Url使用,此时@GET只能指明请求方法,路径参数必须留空 Call<ResponseBody> getContent3(@Url String url); }
@POST
用来指明请求方法和相对/绝对/完整路径,同时也可以配合@Url使用。public interface RequestService { @POST("xx/xxx") //指定相对路径 Call<ResponseBody> getContent1(); @POST("/xxx") //指定绝对路径 Call<ResponseBody> getContent1(); @POST("http://www.baidu.com") //指定完整Url Call<ResponseBody> getContent2(); @POST //配合@Url使用,此时@POST只能指明请求方法,路径参数必须留空 Call<ResponseBody> getContent3(@Url String url); }
- @DELETE,@HEAD,@OPTIONS,@PATCH,@PUT
这几种请求方法和POST/GET在使用上没有太大区别,由于不太常用,这里就不做介绍。
请求参数注解
@Path
该注解用于替换Url的路径(path)部分。public interface RequestService { @GET("/image/{id}") //替换{}内的路径 Call<ResponseBody> getImage(@Path("id") int id); @GET("/user/{name}") //替换{}内的路径 Call<ResponseBody> getUserInfo(@Path("name") String name); @GET("/user/{name}") //替换{}内的路径,encoded=true则表示自己处理编码, Call<ResponseBody> getUserInfo(@Path(value="name", encoded=true) String name); }
上述代码有一个是否需要编码的问题,这里举个例子:假如输入名字
maple+jaw
,默认情况下为GET中的注解为/user/maple%2Bjaw
,如果指明自己处理编码,此时输入maple+jaw
,路径参数为/user/maple+jaw
@Query
该注解用于在Url后追加查询参数public interface RequestService { @GET("/list") //追加查询参数后,此时路径为/list?page=xx Call<ResponseBody> getList(@Query("page") int page); @GET("/list") //追加查询参数后,此时路径为/list?page=xx&category=xx Call<ResponseBody> getList(@Query("page") int page,@Query("category") String category); @GET("/list") //同理也可指定是否编码 Call<ResponseBody> getList(@Query(value="category",encoded=true) String category); }
@QueryMap
@QueryMap和@Query的作用是一样的,只不过@QueryMap是以map的形式追加参数,可以一次性追加多个参数public interface RequestService { @GET("/search") Call<ResponseBody> getList(@QueryMap Map<String, String> filters); }
@Field
该注解用于添加表单数据,须配合@FormUrlEncoded
一起使用。public interface RequestService { @FormUrlEncoded @POST("/register") //使用@Field提交表单数据 Call<ResponseBody> register(@Field("name") String name,@Field("password") String pwd,); @FormUrlEncoded @POST("/register") //使用@Field提交表单数据,encoded=true表示该数据自己编码 Call<ResponseBody> register(@Field(value="name",encoded=true) String name,@Field("password") String pwd,); }
@FieldMap
@Field和@FieldMap的作用一样,后者以map的方式提交表单数据public interface RequestService { @FormUrlEncoded @POST("/register") //使用@FieldMap提交表单数据 Call<ResponseBody> register(@FieldMap Map<String, String> fields); }
@Header
该注解用于指明请求头参数,相同名字的请求头是惟一的,新的会直接覆盖旧的。public interface RequestService { @GET("/") Call<ResponseBody> getContent(@Header("Accept-Language") String lang ,@Header("Cache-Control") String cache); }
@Headers
该注解用于指明请求头参数,和@Header的区别在于不会覆盖掉相同名字的请求参数public interface RequestService { @Headers("Cache-Control: max-age=640000") @GET("/") Call<ResponseBody> getContent(); @Headers({ "Cache-Control: max-age=640000","Accept-Language: gzip, deflate"}) @GET("/") Call<ResponseBody> getContent(); }
@HeaderMap
@HeaderMap和@Headers的作用一样,区别在于以Map的形式指明请求头参数。public interface RequestService { @GET("/search") Call<ResponseBody> getList(@HeaderMap Map<String, String> headers); }
@Part
该注解用于定义分块表单请求中的块。需配合@Multipart一起使用。
如果类型是MultipartBody.Part,内容将直接被使用。(@Part MultipartBody.Part part
)
如果类型是RequestBody,将会和它的contentType一起使用。(@Part("foo") RequestBody foo
)
其他类型将会通过转换器转换后使用。(@Part("foo") Image photo
)
@Part(XX),XX表示表单名。public interface RequestService { @Multipart @POST("/") Call<ResponseBody> example(@Part("des