简介
Retrofit可以将你的HTTP API转换成Java接口。
public interface GitHubService{
@GET("user/{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");
使用注释描述HTTP请求:
- 支持URL参数占位符和查询参数
- Object转换为请求体(例如:JSON,结构化数据)
- Multipart请求体和文件上传
API声明
在接口的方法和方法的形参上的注释,起作用是用来指明一个请求将要如何被处理的。
请求方法
每一个方法必须要有一个用来提供请求方法和相关URL的HTTP注释。有五个固定的注释:GET,POST,PUT,DELETE,HEAD
。注释中要指定请求的资源对应的URL:
@GET("users/list")
你也可以在URL中指定查询参数:
@GET("users/list?sort=desc")
URL处理
你可以在方法上使用占位块和参数来动态的修改URL。占位块是被{}
括起来的数字和字符混合的String
类型数据。对应的参数必须被@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);
请求体
使用了@Body
注释的对象可以被指定作为HTTP请求体使用:
@POST("user/new")
Call<User> createUser(@Body User user);
当使用一个被Retrofit
实例指定的Converter
时,这个对象也将会被修改。如果没有添加converter
,那么只有RequestBody
可以被使用。
FORM ENCODED 和 MULTIPART
方法也可以被声明成用来发送表格数据和Multipart数据。
当方法上被@FormUrlEncoded
注释的时候,Form-encoded数据会被发送。每一个键值对需要被@Field
修饰,它包含了name和value:
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
可以在方法上加上@Multipart
注释来发送Multipart请求。Parts需要使用@Part
注释:
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
Multipart parts使用Retrofit
众多的convert
中的一个,或者可以自己实现一个RequestBody
来处理自己的序列化。
请求头的处理
你可以使用@Headers
注释为每一个方法设置静态的Headers。
@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);
注意,hearders彼此之间互不干扰。有着相同名字的所有headers将会被请求包含。
可以使用@Header
动态的修改一个Header。@Header
后面必须跟着相应的参数。如果参数的值为null,那么这个Header将会被忽视。否则,value 的toString
方法会被调用,并且会被作为结果使用。
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
需要被添加到每次请求的Header可以用OkHttp Interceptor指定。
同步VS异步
Call
可以异步执行,也可以同步执行。每一个实例只可以被使用一次,但是调用clone()
可以生成一个新的可以使用的实例。
在Android中,callbacks
会在主线程中执行,在JVM中,callbacks
会在执行HTTP请求的那个线程中执行。(译者注:直接调用excute
方法为同步执行,调用enqueue
方法为异步执行。)
Retrofit配置
Retrofit
可以将你的API接口转换为可调用的对象。默认情况下,Retrofit
会为你的平台提供匹配的默认值,但是它同样允许定制。
CONVERTERS
默认情况下,Retrofit只能将HTTP body解析成OkHttp的ResponseBody
类型,并且@Body
只接受OkHttp的RequestBody
类型。
为了可以支持其他类型,converters允许被添加。为了你的方便,Retrofit已经适配了六个流行的解析库:
- 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
下面是一个例子,使用GsonConvertFactory
来生成接口GitHubService
的实现,其中接口GitHubService
是使用Gson来解析数据的。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
自定义CONVERTERS
如果你需要使用Retrofit不支持的内容格式和API通信,或者你希望使用一个不同的库来解析已经存在的格式,你可以简单的创建自己的converter。创建一个类,使其继承Converter.Factory
,当创建retrofit的时候将自己的converter作为参数传进去即可。
Download
MAVEN
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>(insert latest version)</version>
</dependency>
GRADLE
compile 'com.squareup.retrofit2:retrofit:(insert latest version)'
Retrofit最低支持Java7 或Android2.3。
PROGUARD
如果你的项目里使用了ProGuard,那么把下面的代码加入到你的配置中去:
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
Retrofit使用了Okio,因此你也需要查看它的ProGuard rules。