简介
Retrofit 将你的HTTP API转换成java接口
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
用Retrofit class 创建一个实现了GitHubService 接口的对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
每个被GitHubService创建的Call能发出一个同步或异步的http请求
Call<List<Repo>> repos = service.listRepos("octocat");
使用注解来描述HTTP请求
- URL支持参数替换和查询参数
- 对象转出成请求体(例如json protocol buffers)
- 多部分请求体和文件上传
API声明
根据在方法和参数声明上的注解,一个请求会怎么被操作
请求Method
每个方法必须有个用来提供请求方式和相关的URL的HTTP注解,有5个内置注解:GET,POST,PUT,DELETE和HEAD,关联资源的URL在注解中指定
@GET("users/list")
You can also specify query parameters in the URL.
你也能指定在URL中的参数
@GET("users/list?sort=desc")
URL处理
一个URL请求能够使用替换块和和方法中的参数更新,一个替换块是一个被{}包裹的字符串。对应的参数必须被用@path使用相同的字符串注解
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
查询参数也能这样被添加
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
至于复杂的查询参数,能够结合map使用
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
Request Body
@Body 注释一个对象能被指定作为一个HTTP请求体。
@POST("users/new")
Call<User> createUser(@Body User user);
在Retrofit实例中使用一个转换器,可以将一个对象转换,如果没有转换器被添加,则只能使用RequestBody
multipart/form-data
方法也能声明成multipart/form-data
当@FormUrlEncoded 出现在方法上是form-data
每个键值对是用@Field注解的,包含了名字以及对应的值
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
当@Multipart出现在method中时,Multipart请求被使用。
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
Multipart parts要使用Retrofit的众多转换器之一或者实现RequestBody来处理自己的序列化。
Header处理
你能使用@Headers设置静态的headler
@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
注意:header是不会相互覆盖的,所有使用相同名字的header都会被包含在请求中
一个请求的Header能被动态更新,通过使用@Header。@Header对应的参数必须被提供,否则参数的toString会被调用并使用其返回值
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
可以使用Okhttp 拦截器头添加每个请求都需要添加的header
同步和异步
Call对象 以同步或是异步的方式被执行,每个对象仅能被执行一次,但是可以调用clone创建一个能被使用的新对象
在Android中,callback在主线程中被执行,在JVM中,callback会在其发送HTTP请求的线程中
Retrofit配置
Retrofit是一个类,通过它将你的API接口转换成可调用的对象,默认的,Retrofit会为根据你的平台给一些合适的默认值,但是它也允许你自定义
转换器
默认的,Retrofit只能将HTTP bodies 反序列化成OkHttp的ResponseBody类型并且它只能接受它自己的RequestBody类型作为参数。通过添加转化器能够支持其它的类型
为了方便你适配常用的序列化哭,提供了6个兄弟模块
Gson: com.squareup.retrofit2:converter-gson
Jackson: com.squareup.retrofit2:converter-jackson
Moshi: com.squareup.retrofit2:converter-moshi
Protobuf: com.squareup.retrofit2:converter-protobuf
Wire: com.squareup.retrofit2:converter-wire
Simple XML: com.squareup.retrofit2:converter-simplexml
Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
这儿有一个使用GsonConverterFactory产生一个实现了GitHubService接口的对象的例子,这个接口使用Gson来反序列化
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
自定义转换器
如果需要使用Retrofit不支持的开箱即用的内容格式(如YAML、txt、自定义格式)和API进行通信或者使用一个不同的库去实现一个已经存在的格式,你能很容易的创造一个你自己的转换器。通过创建一个继承了[Converter.Factoryclass]的类,并且传递一个实例当你构建你的适配器时
.