Retrofit turns your HTTP API into a Java interface.
Retrofit可以将你的HTTP API转化为JAVA的接口
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
The Retrofit class generates an implementation of the GitHubService interface.
通过Retrofit的create方法,就能生成一个GitHubService接口的实现
Retrofit retrofit = new Retrofit.Builder()
GitHubService service = retrofit.create(GitHubService.class);
Each Call from the created GitHubService can make a synchronous or asynchronous HTTP request to the remote webserver.
每一个"来自创建的GitHubService接口的"Call对象,都可以向远程Web服务器发出同步或异步的HTTP请求。
Call<List<Repo>> repos = service.listRepos("octocat");
Use annotations to describe the HTTP request:
- URL parameter replacement and query parameter support。
- Object conversion to request body (e.g., JSON, protocol buffers)。
- Multipart request body and file upload。
Retrofit使用注解来描述HTTP请求:
- URL参数的替换和query参数的支持
- 对象转化为请求体(如:JSON,protocol buffers等)
- 多重请求体和文件上传
2、API Declaration 接口方法声明
Annotations on the interface methods and its parameters indicate how a request will be handled.
接口方法上的注解及其参数,表明一个请求需要怎么样被处理。
【2.1、REQUEST METHOD 请求方法】
Every method must have an HTTP annotation that provides the request method and relative URL. There are five built-in annotations: GET, POST, PUT, DELETE, and HEAD. The relative URL of the resource is specified in the annotation.
每一个方法必须要有一个HTTP注解,来标明请求的方式和相对URL。有五种内置的注解:GET、POST、PUT、DELETE以及HEAD。资源的相对URL需要在注解里面指定:
You can also specify query parameters in the URL.
你也可以将query参数直接写在URL里:
@GET("users/list?sort=desc")
【2.2、URL MANIPULATION URL操作】
A request URL can be updated dynamically using replacement blocks and parameters on the method. A replacement block is an alphanumeric string surrounded by { and }. A corresponding parameter must be annotated with @Path using the same string.
一个请求的URL可以通过"替换块和方法的参数"来进行动态的更新。替换块是由被{}包裹起来的"字母数字字符串"。相应的参数必须使用@Path来注解同样的字符串。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
Query parameters can also be added.
Query参数也能同时被添加。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
For complex query parameter combinations a Map can be used.
对于复杂的query参数,可以用Map来构建
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
【2.3、REQUEST BODY 请求体】
An object can be specified for use as an HTTP request body with the @Body annotation.
可以通过@Body注解来指定一个对象作为HTTP请求主体
@POST("users/new")
Call<User> createUser(@Body User user);
The object will also be converted using a converter specified on the Retrofit instance. If no converter is added, only RequestBody can be used.
这个对象会被Retrofit实例中指定的converter进行转化。如果没有给Retrofit实例添加任何converter,则只能使用RequestBody。
【2.4、FORM ENCODED AND MULTIPART 表单编码和多个】
Methods can also be declared to send form-encoded and multipart data.
方法也可以通过声明来发送form-encoded和multipart类型的数据。
Form-encoded data is sent when @FormUrlEncoded is present on the method. Each key-value pair is annotated with @Field containing the name and the object providing the value.
当方法中存在@FormUrlEncoded注解时,会发送表单编码数据。每个键值对都(需要)用@Filed来注解,其中包含名称和提供该值对象。
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
Multipart requests are used when @Multipart is present on the method. Parts are declared using the @Part annotation.
当方法中存在@Multipart注解时,将使用Mutipart请求。Parts需要使用@Part注解来声明。
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
Multipart parts use one of Retrofit‘s converters or they can implement RequestBody to handle their own serialization.
多个部件使用Retrofit其中的一个转换器,或者他们可以实现RequestBody来处理自己的序列化。
【2.5、HEADER MANIPULATION 头部操作】
You can set static headers for a method using the @Headers annotation.
你可以通过使用@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);
Note that headers do not overwrite each other. All headers with the same name will be included in the request.
请注意,头部参数并不会相互覆盖。具有同一个名称的所有头参数都会被包含进请求里面(即:允许key重复)。
A request Header can be updated dynamically using the @Header annotation. A corresponding parameter must be provided to the @Header. If the value is null, the header will be omitted. Otherwise, toString will be called on the value, and the result used.
可以使用@Header注解动态更新请求头。 相应的参数必须提供给 @Header 注解。 如果这个值为null,那么这个头部参数就会被忽略。 否则,值的 toString 方法将会被调用,并且使用此结果。
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
可以使用OkHttp拦截器来指定需要添加到每个请求中的头部参数。
【2.6、SYNCHRONOUS VS. ASYNCHRONOUS 同步 VS 异步】
Call instances can be executed either synchronously or asynchronously. Each instance can only be used once, but calling clone() will create a new instance that can be used.
你可以同步或者异步地来执行Call实例。每个实例只能被使用一次,但是调用 clone() 后将会创建一个可以使用的新的实例。
On Android, callbacks will be executed on the main thread. On the JVM, callbacks will happen on the same thread that executed the HTTP request.
在Android中,callback将会在主线程中执行;而在JVM环境中,callback将发生在和执行Http请求相同的那个线程中。
3、Retrofit Configuration 配置
Retrofit is the class through which your API interfaces are turned into callable objects. By default, Retrofit will give you sane defaults for your platform but it allows for customization.
Retrofit是将你定义的API接口转换为可调用对象的类。 默认情况下,Retrofit会提供给你"对您的平台来说"比较理智的默认值,但它允许自定义。
【3.1、CONVERTERS 转换器】
By default, Retrofit can only deserialize HTTP bodies into OkHttp‘s ResponseBody type and it can only accept its RequestBody type for @Body.
默认情况下,Retrofit只能将HTTP消息体反序列化为OKHttp的 ResonseBody 类型,而且只能接收 RequestBody 类型作为 @Body。
Converters can be added to support other types. Six sibling modules adapt popular serialization libraries for your convenience.
可以添加转换器来支持其他类型。 以下六个同级模块,采用了常用的序列化库,来为你提供方便。
- 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
Here‘s an example of using the GsonConverterFactory class to generate an implementation of the GitHubService interface which uses Gson for its deserialization.
下面提供一个使用GsonConverterFactory类生成 GitHubService 的接口实现(通过使用Gson反序列化)的例子。
以下是使用GsonConverterFactory类生成使用Gson进行反序列化的GitHubService接口的实现的示例。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())//GsonConverterFactory
.build();
GitHubService service = retrofit.create(GitHubService.class);
【3.2、CUSTOM CONVERTERS 自定义转化器】
If you need to communicate with an API that uses a content-format that Retrofit does not support out of the box (e.g. YAML, txt, custom format) or you wish to use a different library to implement an existing format, you can easily create your own converter. Create a class that extends the Converter.Factory class and pass in an instance when building your adapter.
如果你需要与,没有使用Retrofit提供的内容格式的API,进行交互(例如YAML、txt、或自定义格式),或者是你希望使用一个不同的库,来实现现有的格式,你可以轻松创建你自己的转化器。你需要创建一个继承自Converter.Factory的类,并且在构建适配器的时候传递一个实例。
2017-9-7