第一讲:Retrofit概述——它到底是什么?

大家好,欢迎来到这门实战课。

今天我们来聊聊 Retrofit。很多人觉得它就是个网络请求库,嗯,其实不太准确。说白了,Retrofit 是 Square 公司出品的一个 HTTP 客户端封装工具。它的核心思想就是——用注解把你定义的 Java 接口方法,变成真正的网络请求。

我记得早期做 Android 开发时,大家都是手写 HttpURLConnection,或者用 Volley。那时候写个网络请求,要处理线程、解析 JSON、还得考虑错误回调,代码一大坨。后来 Retrofit 出来后,团队里的老大哥就说了一句:“这玩意儿,能让你的网络层代码变得像诗一样优雅。” 我当时半信半疑,直到自己上手用了,才明白他说的意思。

一句话总结:Retrofit = 注解定义接口 + 动态代理生成实现 + 自动解析响应。

核心概念三件套

要理解 Retrofit,你只需要抓住三个东西:接口、注解、Converter。

咱们一个一个说。

1. 接口(Interface)

Retrofit 要求你定义一个 interface,里面声明你要请求的网络 API 方法。注意,它不是一个普通的类,而是接口。为什么?因为 Retrofit 会通过 Java 的动态代理机制,在运行时为你这个接口生成真正的实现对象。

听起来有点玄乎?我举个例子你就懂了。

public interface GitHubService {
    @GET("users/{user}/repos")
    Call<List<Repo>> listRepos(@Path("user") String user);
}

你看,这个接口里只有一个方法 listRepos。它上面标注了 @GET 注解,表示这是一个 GET 请求,路径是 users/{user}/repos。方法参数 @Path("user") 用来动态替换路径中的占位符。

你想想看,如果让你自己写这段代码,你得手动拼接 URL、处理异步、还要解析 JSON。而 Retrofit 帮你把这些脏活累活全部扛了。

我的建议:很多人会把所有 API 接口写在一个大接口里,我不推荐这样做。按业务模块拆分,比如 UserService、OrderService、ProductService,这样后期维护起来清爽得多。

2. 注解(Annotations)

注解是 Retrofit 的灵魂。没有注解,Retrofit 无法知道你要发什么类型的请求。

常用的注解有这么几类:

类别 注解名称 作用
请求方法 @GET、@POST、@PUT、@DELETE、@PATCH、@HEAD 指定 HTTP 方法类型
URL 参数 @Path、@Query、@QueryMap 替换路径变量或添加查询参数
请求体 @Body 将对象序列化为请求体
请求头 @Header、@Headers 添加自定义请求头
表单 @FormUrlEncoded、@Field、@FieldMap 发送表单格式数据

拿 @Query 举个例子。假设你要搜索 GitHub 上的仓库,搜索关键词是 "retrofit":

@GET("search/repositories")
Call<RepoSearchResult> searchRepos(@Query("q") String query);

这样 Retrofit 会自动帮你拼出 /search/repositories?q=retrofit 这个 URL。是不是很省心?

注意:我曾经踩过一个坑——在同一个方法里既用了 @Body 又用了 @QueryMap。结果发现请求体里多了一堆奇怪的字符。Retrofit 不允许同一个方法既发送请求体又在 URL 中带大量复杂参数,两者会打架。遇到这种情况,建议把参数放进 @Body 里自定义一个结构体。

3. Converter(数据转换器)

接口定义完了,注解写好了,接下来请求发出去,服务器返回的 JSON 怎么变成你需要的 Java 对象?这就轮到 Converter 出场了。

Retrofit 本身不负责序列化和反序列化。它把这个任务外包给了 Converter。官方最常用的搭配是 GsonConverterFactory 或 MoshiConverterFactory。当然,你也可以写一个自定义的 Converter,这在后面 Mock 适配器的章节中会用到。

配置起来很简单:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

GitHubService service = retrofit.create(GitHubService.class);

这几行代码做完,retrofit 就能把你定义的接口方法,转换成真正的网络请求,并把返回的 JSON 自动解析成 List<Repo> 对象。

小提示:如果你用 Kotlin,我推荐用 kotlinx.serialization 配合 Retrofit 的 KotlinxSerializationConverter,性能比 Gson 更好,而且对 Kotlin 数据类支持更丝滑。

核心逻辑流程图

为了让各位更直观地理解 Retrofit 的运作流程,我画了张图。这张图反映了从定义接口到发出请求的全链路。后面搭建 Mock 适配器时,你会反复用到这个流程。

Retrofit 核心工作流程 定义接口与注解 构建 Retrofit 实例(Builder) 动态代理 → 创建接口实现对象 OkHttp 执行实际 HTTP 请求 Converter 将 Response 转为 Java 对象 返回 Call / Response 对象

Retrofit 的优点——为什么选它?

市面上有那么多网络请求框架,为什么 Retrofit 能成为业界标配?我列几个点:

  • 类型安全——接口定义即契约,编译时就检查,运行时不容易出奇异 bug。
  • 扩展性强——Converter 和 CallAdapter 都可以自定义,这为后面做 Mock 适配器提供了完美的切入点。
  • 与 OkHttp 深度绑定——底层复用 OkHttp 的连接池、拦截器、日志,性能有保障。
  • 社区活跃——你几乎能找到所有常见数据格式的 Converter 实现,从 JSON 到 Protobuf 都有人做了。

适用场景

做纯 RESTful API 的项目,Retrofit 是当仁不让的首选。但如果你需要处理长连接、WebSocket 或者复杂的流式上传下载,它就不太合适了,这时候需要更底层的 OkHttp 甚至 Okio 来搞定。