Android网络(四)网络框架的集大成者--Retrofit

引言

在 Android 开发的历程中,网络请求技术栈经历了从原生的 `HttpUrlConnection` 和 Apache 的 `HttpClient` 到各种封装框架的演变,例如 `Volley` 和 `Async Http Client`。这些工具为开发者提供了多种选择。然而,在众多网络框架中,Square 公司开源的 `Retrofit` 因其简洁的接口设计、强大的扩展性,以及优雅的架构,成为了众多开发者的首选。值得一提的是,`Retrofit` 并不是一个独立的网络请求框架,它主要负责 RESTful 接口的封装。从 2.0 版本开始,`Retrofit` 默认集成了 `OkHttp` 作为底层的网络请求库,`Retrofit` 专注于接口封装,而 `OkHttp` 则承担了高效的网络请求处理任务。两者的结合,为开发者提供了一个灵活且高效的网络通信解决方案。

设计思想

Retrofit 的设计思想围绕着分工协作的理念展开。它并不直接负责网络请求的实现,而是专注于将 RESTful 风格的 HTTP API 转换为 Java 接口。具体的网络请求工作由内部集成的 OkHttp 来完成,这种分离使得 Retrofit 能专注于接口的封装和解析逻辑,从而提升了框架的灵活性和可扩展性。

Retrofit 的核心设计思想可以总结为以下几点:

接口抽象:通过定义接口来描述 API 调用,将实际的网络请求与业务逻辑隔离开。这种设计使得代码更为简洁易懂,接口的定义也更加直观。

动态代理:在调用 create 方法时,Retrofit 会生成该接口的动态代理对象。这个代理对象的每个方法调用都会通过动态代理机制,最终映射为具体的 HTTP 请求。代理对象在运行时根据接口定义和注解信息,自动构建请求的 URL、请求头和请求体,并调用底层的 OkHttp 发送请求。

注解驱动:Retrofit 通过注解来配置 HTTP 方法(如 GET、POST 等)、URL 路径参数、查询参数、请求头信息等。注解的使用让开发者无需手动构建请求,减少了冗余代码,提高了开发效率。

数据解析与转换:Retrofit 内置了多种数据转换器,如 Gson、Moshi 等,用于将服务器返回的 JSON 数据自动解析为 Java 对象。这种自动化的数据转换简化了开发者处理响应数据的工作,使得代码更加简洁。

在实际应用中,开发者只需定义一个接口,并通过 Retrofit.create() 方法生成相应的代理对象。然后通过调用该代理对象的方法,即可实现与服务器的通信,而不需要关心底层的网络请求细节。这种封装极大地方便了 API 的调用和测试。

基本用法

添加依赖

首先依然是添加依赖

dependencies{
...
implementation'com.squareup.retrofit2:retrofic:2.9.0'
implementation'com.squareup.retrofit2:converter-gson:2.9.0'
}

第二条中的GSON是Retrofit常用的转换库,在之后的文章里会详细介绍,这里只需要了解Retrofit是借助GSON来解析JSON数据的即可。

相信大家在学习java的时候已经接触过一些电商类的应用或网站的项目开发了,这些项目在实现电商应用的商品详情页面时,通常会采用 HttpURLConnection 来处理网络请求,并手动解析服务器返回的 JSON 数据,这样需要编写大量的样板代码来完成相同的任务,接下来我们来试试用Retrofit实现商品详情页的数据获取功能,

定义返回数据的模型类

首先我们定义返回数据的模型类,通过定义数据模型类,将服务器返回的商品详情页面,名称、描述、价格和图片等信息的 JSON 格式数据直接映射为 Kotlin 对象,从而避免手动解析 JSON 可能引发的错误。

data class ProductDetails(
    val name: String,
    val description: String,
    val price: Double,
    val imageUrl: String
)

这样,我们可以将服务器返回的 JSON 数据自动映射到 ProductDetails 类的实例中,简化了数据的处理过程。

定义 API 接口

接下来定义 API 接口,将网络请求的定义与实际调用分离。这种接口定义方式使代码结构更加清晰,有利于后期的扩展和维护。接口方法还可以定义请求参数和返回类型,从而使网络请求更加简洁和直观。

interface ProductService {
    @GET("product/details")
    suspend fun getProductDetails(
        @Query("product_id") productId: String
    ): Response<ProductDetails>
}

通过定义 ProductService 接口,我们将网络请求的细节封装起来,使得调用更加简单。

创建 Retrofit 实例 发起网络请求

定义完返回数据的模型类和API接口后,创建 Retrofit 实例配置基础 URL 和 JSON 数据的转换方式,最后通过接口实例发起请求就完成数据获取了

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

这里创建了一个 Retrofit 实例,baseUrl 是服务器的基础 URL,addConverterFactory(GsonConverterFactory.create()) 表示我们使用 GsonConverterFactory 将 JSON 数据自动解析为 Kotlin 对象。

runBlocking {
    val response = service.getProductDetails(101)
    if (response.isSuccessful) {
        val product = response.body()
        println("Product Name: ${product?.name}")
        println("Description: ${product?.description}")
        println("Price: ${product?.price}")
        println("Image URL: ${product?.imageUrl}")
    } else {
        println("Request failed with code: ${response.code()}")
    }
}

这里使用 runBlocking 来启动协程,并通过 service.getProductDetails(101) 发起网络请求。response.isSuccessful 判断请求是否成功,成功则提取商品详情数据并打印,否则打印错误码。

这里面到使用到的一些常见的组件这里单独说一下

Retrofit.Builder():用于构建 Retrofit 实例,并配置基础 URL 和数据转换器。

create():创建 ProductService 接口的实现,这个实现会在运行时动态代理接口方法,将方法调用转换为实际的 HTTP 请求。

@GET:Retrofit 里的一个注解,用于标识 HTTP 请求方法,Retrofit中提供了一系列的HTTP方法注解,如@POST@PUT@DELETE等。

Response<T>:封装了服务器的响应数据和状态码。

总结

Retrofit作为一个成熟且广泛使用的网络库,以其声明式的API、动态代理以及注解驱动的设计,为我们提供了一种简洁而强大的网络请求构建方式,Retrofit对Kotlin协程的原生支持,让它在处理异步网络请求和数据流方面也成为主流。

本篇涉及了一点JSON数据解析,JSON和XML是数据表达的两种主流格式,后面计划将JSON和XML的常用解析库,以及开发实践等详细介绍另开一篇加入专栏。

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值