第2章 Retrofit框架核心概念回顾
这一章我打算带你把Retrofit的底裤翻一翻。说白了,Retrofit就是一个壳,它把三个核心零件组装在一起:注解、OkHttp、CallAdapter。你如果能搞懂它们怎么分工,后面的回放测试方案才能落地。
我个人习惯把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
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 三者如何协作
好的,我们把这三个零件串起来看流程:
- 定义阶段:你写一个接口,用 @GET/@POST 等注解标记方法,用 @Path/@Query/@Body 标记参数。
- 创建 Retrofit 实例:传入 baseUrl、OkHttpClient、CallAdapter.Factory 等。
- 生成代理对象:调用
retrofit.create(ApiService.class),内部通过动态代理生成了接口实现。 - 发起调用:当你调用代理方法时,Retrofit 解析注解生成 OkHttp 的 Request 对象。
- 执行请求:OkHttp 通过网络发送请求,拿到 Response(可能成功也可能失败)。
- 转换结果:CallAdapter 把 Call 或 Response 转换成你声明的返回类型(如 Observable、Deferred)。
这条链路的每一个步骤,我们都可以"插入"回放测试的逻辑。比如在 OkHttp 拦截器层截获请求并返回预录制数据,或者在 CallAdapter 层原地替换。后面章节会深入细节。
回顾总结:注解负责"定义"、OkHttp 负责"执行"、CallAdapter 负责"转换"。搞清这三者的边界,回放测试方案才能对症下药。