当前位置: 首页 > news >正文

深入剖析Retrofit系列(一)来自官方的Retrofit开发手册(中英互译)

Introduction

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类会自动生成GithubService接口的实现。
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

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, 都会生成一个同步或异步的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

使用注解来描述Http请求:
.URL参数替换和查询参数支持
.对象转换为请求体
.Multipart请求体和文件上传

API定义

Annotations on the interface methods and its parameters indicate how a request will be handled.

接口方法和它的参数注解指定了如何处理一个请求。

请求方法

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.

每一个方法必须提供一个提供了相对路径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操作

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.

对于复杂的查询参数组合, 可以使用Map。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
复制代码

RequestBody

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进行转换。 如果没有添加converter, 只能只能使用RequestBody。

FORM ENCODED AND MULTIPART

Methods can also be declared to send form-encoded and multipart data.

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.

也可以在方法上添加form-encoded 和 multipart数据。
当在方法上添加@FormUrlEncoded注解, 将会发送Form-encoded数据。 每个键值对都包含名称的@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注解, Multipart请求会被使用。 Parts是使用@Parts来定义的。
@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.

Multipart 部分使用Retrofit的转换器, 或者它们可以通过自己的RequestBody来实现自己的序列。

Header操作

You can set static headers for a method using the @Headers annotation.

你可以使用@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);
复制代码

Note that headers do not overwrite each other. All headers with the same name will be included in the request.

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.

注意: headers不会相互覆盖, 所有加入的同名headers都会被添加到请求中。
一个请求的header可以使用@Header动态修改。 必须给@Header提供相应的参数。 如果值是空的, header将不会添加到请求。 否则, value的toString()会被调用, 并使用其结果。
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
复制代码

Similar to query parameters, for complex header combinations, a Map can be used.

和Query参数类似, 对于复杂的header组合, 请使用Map。
@GET("user")
Call<User> getUser(@HeaderMap Map<String, String> headers)
复制代码

Headers that need to be added to every request can be specified using an OkHttp interceptor.

如果想统一添加headers, 请使用OkHttp的拦截器。

同步 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.

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.

Call对象既可以同步执行, 也可以异步执行。 每个对象只能使用一次, 但是调用clone()可以创建一个新对象来使用。
在Android中, 会在主线程执行回调。 在JVM中, 回调会发生在和请求同一个线程中。

Retrofit配置

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将会为你的平台提供合理的默认值,但是它允许自定义。

转换器

By default, Retrofit can only deserialize HTTP bodies into OkHttp's ResponseBody type and it can only accept its RequestBody type for @Body.

默认情况下, Retrofit只能将请求主体反序列化为OkHttp的ResponseBody类型。 它的@Body只能接收RequestBody类型。

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

你可以添加Converters来支持其他类型。 下面有6个主流的的反序列化库供您使用:
Gson, Jackson, Moshi, Protobuf, Wire, SimpleXML, 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进行反序列化。
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

GitHubService service = retrofit.create(GitHubService.class);
复制代码

自定义转换器

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, 或你希望使用一个不同的库来实现已经存在的格式, 你可以轻松的创建你自己的Converter。 创建一个类继承Converter.Factory,并在你构建适配器的时候传进一个对象。

引入

MAVEN

<dependency>
  <groupId>com.squareup.retrofit2</groupId>
  <artifactId>retrofit</artifactId>
  <version>(insert latest version)</version>
</dependency>
复制代码

GRADLE

implementation 'com.squareup.retrofit2:retrofit:(insert latest version)'
复制代码
注意事项: Retrofit需要最低Java7 和 Android 2.3。
如果你正在使用R8, 或者ProGuard
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature

# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}

# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**
复制代码

官方解释结束。 最终发现, Retrofit只做了一件事, 就是把Request的数据转换为Response返回数, 并简化了请求和返回的过程。

相关文章:

  • java编程——高并发大容量NoSQL解决方案探索
  • Android 模拟器下载、编译及调试
  • [译]常见网页设计错误一览
  • 面试官告诉你如何准备Java初级和高级的技术面试
  • Apache Pulsar 2.1 重磅发布
  • java监听器实现与原理
  • Jenkisn行RFS脚本问题汇总
  • 【模板】最小生成树
  • angular1.x 性能优化
  • sublime打开文本时会记忆上次关闭时鼠标停留的位置
  • 模板汇总——AC自动机
  • vue keep-alive组件
  • SQL Server CONVERT() 函数
  • JS一元操作符递增与递减
  • VUE - eslint - 笔记
  • [译] React v16.8: 含有Hooks的版本
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Apache的80端口被占用以及访问时报错403
  • C# 免费离线人脸识别 2.0 Demo
  •  D - 粉碎叛乱F - 其他起义
  • docker python 配置
  • HashMap剖析之内部结构
  • javascript面向对象之创建对象
  • JAVA之继承和多态
  • Just for fun——迅速写完快速排序
  • laravel 用artisan创建自己的模板
  • rabbitmq延迟消息示例
  • Redis的resp协议
  • SpiderData 2019年2月23日 DApp数据排行榜
  • Theano - 导数
  • Vue全家桶实现一个Web App
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 使用docker-compose进行多节点部署
  • 提醒我喝水chrome插件开发指南
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • 浅谈sql中的in与not in,exists与not exists的区别
  • #pragma once与条件编译
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (12)Linux 常见的三种进程状态
  • (4) PIVOT 和 UPIVOT 的使用
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (三)Honghu Cloud云架构一定时调度平台
  • (算法二)滑动窗口
  • (转)负载均衡,回话保持,cookie
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .gitignore文件_Git:.gitignore
  • .gitignore文件---让git自动忽略指定文件
  • .htaccess配置重写url引擎