Skip to content

Retrofit Doc 译

Published: at 00:00

为加深对Retrofit网络请求框架的理解,遂将官网Doc通读一遍并翻译成中文。

引言

Retrofit将你的HTTP API换成Java接口。

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

Retrofit 类生成一个 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");

使用注解(annotations)的方式来来描述一个HTTP请求:

API 说明

接口中方法以及其参数的注解用于表明这个请求会被处理的方式。

请求方法

每个方法都必须有一个声明了请求类型和相对URL地址的HTTP注解,内置支持五种类型注解:GET,POST,PUT,DELETE,HEAD,相对URL地址在注解中进行指定。

@GET("users/list")

也可以直接在URL中写请求参数。

@GET("users/list?sort=desc")

URL操作

通过在方法中使用替换块和参数,可以实现请求URL地址的动态更新。一个替换块(replacement block)是一个由花括号“{…}”包裹的字符串,与之通信的参数必须使用 @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 实例中指定的转换器(Converter)进行转换。如果没有指定转换器,则只能使用 RequestBody

表单数据及操作

可以声明方法来发送表单以及多请求体数据。 当方法上出现 @FormUrlEncoded 时会发送表单形式的数据,键值对通过 Field 注解来声明。

@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);

当方法上出现 @Multipart 时会以多请求体的形式发送数据。每一部分使用 @Part 注解。

@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

此部分需要使用 Retrofit

请求头部操作

可以使用 @Header 注解为每一个方法设置静态请求头部。

@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 注解来进行动态更新,如果参数的对象值为null,该头部将会被忽略;否则会调用 toString() 方法来取得值。

@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

每个请求都使用的头部Header可以使用OkHttp interceptor来指定

同步 VS 异步

Call 的实例既可以同步执行,也可以异步执行;每个实例只能使用一次,可以调用 clone() 方法来创建一个新的实例使用。 在Android上,回调(callbacks)会在主线程中执行;在JVM中,回调会在执行HTTP请求的线程中执行。

Retrofit 配置

Retrofit 是一个可以把你的API接口转换成可被调用的对象的类。默认情况下,Retrofit会为你的平台提供合理的默认配置,同时它也支持自定义配置。

转换器(Converters)

默认情况下,Retrofit只能将HTTP请求体反序列化成OkHttp的 RetrofitBody 类型,而且 @Body 也只接受 RetrofitBody 类型。 添加转化器可以支持其他的类型。为了方便使用,以下六个流行的序列化库已被支持(retrofit 2)。

一个使用 GsonConverterFactory 类来生成 GitHubService 实例的例子。

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

GitHubService service = retrofit.create(GitHubService.class);

自定义转化器

如果与API的通信使用了Retrofit不支持的格式的内容,或者希望使用一个不同序列化库,那么就需要创建一个自定义的Converter。集成 Converter.Factory 类创建一个新类,并且在build Retrofit的时候传入该类的实例。

参考资料