第2章 Retrofit框架核心概念回顾

这一章我打算带你把Retrofit的底裤翻一翻。说白了,Retrofit就是一个壳,它把三个核心零件组装在一起:注解、OkHttp、CallAdapter。你如果能搞懂它们怎么分工,后面的回放测试方案才能落地。

我个人习惯把Retrofit拆成三块来看。第一块是"定义",用注解把接口描述清楚;第二块是"执行",交给OkHttp去发请求;第三块是"转换",CallAdapter把网络返回变成你想要的类型。嗯,就这么简单。但简单背后藏着不少坑,我一个个说。

Retrofit 核心三件套协作关系 注解(@GET等) OkHttp(网络执行) CallAdapter(结果转换) Retrofit 实例(代理工厂) Request(请求) Response(响应/错误) 三大组件通过 Retrofit 代理串联:注解定义接口 → OkHttp 发起请求 → CallAdapter 转换结果

2.1 注解驱动的接口定义

Retrofit 最讨喜的地方,就是用注解定义 HTTP 请求。你不需要手写一行网络代码,只要写个接口,加几个注解就行。

我记得刚做 Android 那会儿,有人拿 Retrofit 的 @Path 和 @Query 搞混了。接口路径上该用占位符的地方,他用了 @Query,结果请求 URL 多了一个问号参数,服务端死活不认。后来排查了俩小时才发现。

常用注解大概分两类:

方法注解 参数注解
@GET / @POST / @PUT / @DELETE @Path — 替换路径占位符
@Headers — 添加固定请求头 @Query — 拼接 URL 查询参数
@FormUrlEncoded — 表单编码 @Body — 请求体(JSON 序列化)
@Multipart — 文件上传 @Header — 动态请求头

关键点:注解只定义"协议",不负责执行。代理对象被调用时,Retrofit 才会把注解信息翻译成 OkHttp 的 Request 对象。

2.2 OkHttp:底层的网络执行引擎

Retrofit 默认把 OkHttp 当作底层 HTTP 客户端。原因很简单:OkHttp 够快、够稳定,还自带连接池、重连、拦截器。

我曾在项目里加过一个日志拦截器,调试阶段特别爽——能看到完整的请求 URL、请求头、响应体。上线前我把它关掉了,免得日志刷爆存储。

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC))
    .connectTimeout(10, TimeUnit.SECONDS)
    .build();

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .client(client)
    .build();

小技巧:你可以在 OkHttp 层加一个"拦截器"来做回放测试的核心。后面章节我会讲怎么用拦截器拦截请求、模拟响应,现在先记住 OkHttp 是改造的关键入口。

2.3 CallAdapter:让你的接口更灵活

默认 Retrofit 的接口方法返回 Call。但现实项目中,我们通常需要返回 RxJava 的 Observable、Kotlin Coroutines 的 Deferred,或者直接走 LiveData。

CallAdapter 就是干这个的。它把 Call 包装成你想要的类型。Retrofit 内置了 CallAdapter.Factory,也支持你自定义。

举个例子,加入 RxJava 支持:

// 添加依赖后
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .build();

// 接口方法直接返回 Observable<User>
public interface ApiService {
    @GET("user/{id}")
    Observable<User> getUser(@Path("id") int id);
}

避坑:我曾经遇到一个问题——接口返回的是 Call,但自定义了 CallAdapter 之后,类型不匹配导致崩溃。后来发现是因为 Retrofit 里注册了多个 CallAdapter.Factory,优先级不对。建议给 addCallAdapterFactory 指定顺序,或者只保留一个。

2.4 三者如何协作

好的,我们把这三个零件串起来看流程:

  1. 定义阶段:你写一个接口,用 @GET/@POST 等注解标记方法,用 @Path/@Query/@Body 标记参数。
  2. 创建 Retrofit 实例:传入 baseUrl、OkHttpClient、CallAdapter.Factory 等。
  3. 生成代理对象:调用 retrofit.create(ApiService.class),内部通过动态代理生成了接口实现。
  4. 发起调用:当你调用代理方法时,Retrofit 解析注解生成 OkHttp 的 Request 对象。
  5. 执行请求:OkHttp 通过网络发送请求,拿到 Response(可能成功也可能失败)。
  6. 转换结果:CallAdapter 把 Call 或 Response 转换成你声明的返回类型(如 Observable、Deferred)。

这条链路的每一个步骤,我们都可以"插入"回放测试的逻辑。比如在 OkHttp 拦截器层截获请求并返回预录制数据,或者在 CallAdapter 层原地替换。后面章节会深入细节。

回顾总结:注解负责"定义"、OkHttp 负责"执行"、CallAdapter 负责"转换"。搞清这三者的边界,回放测试方案才能对症下药。