开始使用Retrofit 2 HTTP 客户端

Retrofit 是一种用于Android和Java的类型安全的HTTP客户端。 Retrofit通过将API转换为Java接口来轻松连接到REST Web服务。 在本教程中,我将向您介绍如何使用Android上最流行和经常推荐的HTTP库之一。

这个强大的库可以方便地使用JSON或XML数据,然后将其解析为普通Java对象(POJO)。 GET,POST,PUT,PATCH和DELETE请求都可以执行。

像大多数开源软件一样,Retrofit基于一些其他强大的库和工具。 在幕后,Retrofit使用OkHttp(来自同一个开发人员)处理网络请求。 此外,Retrofit没有内置的任何JSON转换器来解析从JSON到Java对象。 相反,它支持以下JSON转换器库来处理:

  • Gson: com.squareup.retrofit:converter-gson
  • Jackson: com.squareup.retrofit:converter-jackson
  • Moshi: com.squareup.retrofit:converter-moshi

For Protocol Buffers, Retrofit 支持:

  • Protobuf: com.squareup.retrofit2:converter-protobuf
  • Wire: com.squareup.retrofit2:converter-wire

And for XML, Retrofit 支持:

  • Simple Framework: com.squareup.retrofit2:converter-simpleframework

开发自己的类型安全HTTP库以与REST API交互可能是一个真正的痛苦:你必须处理许多功能,如进行连接,缓存,重试失败的请求,线程,响应解析,错误处理等等。 改造,另一方面,是非常好的计划,文件和测试 - 一个经过考验的图书馆,将为您节省大量宝贵的时间和头痛。
在本教程中,我将解释如何使用Retrofit 2来处理网络请求,方法是构建一个简单的应用程序,以查询Stack Exchange API的最新解答。 我们将通过指定一个endpoint- / answers,附加到基本URL https://api.stackexchange.com/2.2,然后获取结果并在回收站视图中显示它们来执行GET请求。 我也将告诉你如何做到这一点与RxJava易于管理的状态和数据的流。

启动Android Studio并创建一个名为MainActivity的空活动的新项目。

Create a new empty activity

创建新项目后,在build.gradle中声明以下依赖项。 依赖关系包括回收器视图,Retrofit库,以及Google的Gson库,用于将JSON转换为POJO(普通Java对象)以及Retrofit的Gson集成。

不要忘记同步项目以下载这些库。

要执行网络操作,我们需要在应用程序清单中包含INTERNET权限:AndroidManifest.xml。

我们将通过利用一个非常有用的工具,从JSON响应数据中自动创建模型: jsonschema2pojo

在浏览器的地址栏中复制并粘贴https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow(如果您熟悉该工具,则可以使用Postman)。 然后按Enter键,这将在给定端点上执行GET请求。 你会看到响应是一个JSON对象数组。 下面的截图是使用Postman的JSON响应。

API response to GET request

从浏览器或Postman复制此JSON响应。

现在访问jsonschema2pojo并将JSON响应粘贴到输入框中。
选择JSON的源类型,Gson的注释样式,并取消选中允许其他属性。

jsonschema2pojo interface

然后单击“预览”按钮以生成Java对象。

jsonschema2pojo output

你可能想知道@SerializedName和@Expose注释在这个生成的代码中做什么。 别担心,我会解释一切!
Gson使用@SerializedName注释来将JSON键映射到我们的字段。 为了遵守Java的关于类成员属性的camelCase命名约定,不建议使用下划线来分隔变量中的单词。 @SerializedName有助于在两者之间进行转换。

在上面的示例中,我们告诉Gson我们的JSON键quota_remaining应该映射到Java字段quotaRemaining。 如果这两个值相同,即如果我们的JSON键是quotaRemaining,就像Java字段一样,那么字段上不需要@SerializedName注释,因为Gson会自动映射它们。
@Expose注释表示该成员应该公开用于JSON序列化或反序列化。

现在让我们回到Android Studio。 在主包中创建一个新的子包并将其命名为数据。 在新创建的数据包内,创建另一个包并将其命名为model。 在模型包内,创建一个新的Java类并将其命名为Owner。 现在复制由jsonschema2pojo生成的Owner类,并将其粘贴到您创建的Owner类中。

对新的Item类执行相同的操作,从jsonschema2pojo复制。

最后,为返回的StackOverflow答案创建一个名为SOAnswersResponse的类。 您将在jsonschema2pojo中找到此类的代码作为示例。 确保您将类名称更新为SOAnswersResponse,无论它发生在哪里。

要使用Retrofit向REST API发出网络请求,我们需要使用Retrofit.Builder类创建一个实例,并使用基本URL配置它。
在数据包内创建一个新的子包包,并将它命名为remote。 现在在远程,创建一个Java类,并命名为RetrofitClient。 这个类将创建一个单一的Retrofit。 Retrofit需要一个基本URL来构建其实例,因此当调用RetrofitClient.getClient(String baseUrl)时,我们将传递一个URL。 这个URL将用于在第13行中构建实例。我们还在第14行中指定了我们需要的JSON转换器(Gson)。

在远程包中,创建一个接口并调用它SOService。 此接口包含我们将用于执行HTTP请求(如GET,POST,PUT,PATCH和DELETE)的方法。 对于本教程,我们将执行GET请求。

@GET注释显式地定义了一旦该方法被调用就将被执行的GET请求。 此接口中的每个方法都必须具有提供请求方法和相对URL的HTTP注释。 有五个内置注释可用:@GET,@POST,@PUT,@DELETE和@HEAD。
在第二个方法定义中,我们添加了一个查询参数,用于从服务器过滤数据。 Retrofit使用@Query(“key”)注释来代替在端点中对其进行硬编码。 键值表示URL中的参数名称。 它将被Retrofit添加到URL。 例如,如果我们将值“android”作为参数传递给getAnswers(String tags)方法,则完整的URL将是:

接口方法的参数可以有以下注释:

@Path API端点的变量替换
@Query使用带注释参数的值指定查询键名称
@BodyPOST调用的有效内容
@Header指定带有注释参数值的标题

现在要创建一个实用程序类。 我们将其命名为ApiUtils。 此类将基本URL作为静态变量,并通过getSOService()静态方法为我们的应用程序提供SOService接口。

由于结果将显示在回收站视图(recycler view)中,因此我们需要一个适配器。 下面的代码片段显示了AnswersAdapter类。