Retrofit + OkHttp
1. 先定义接口(你写的 ApiService)
interface ApiService {
// 定义一个请求
@GET("user/info")
suspend fun getUserInfo(): UserBean
}
2. 构建 Retrofit + 拿到 ApiService实例
object RetrofitManager {
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
// 1. RetryAndFollowUpInterceptor(重试、重定向)
.addInterceptor(RetryAndFollowUpInterceptorBuilder().build())
// 2. BridgeInterceptor(补全头、编码、Cookie)
.addInterceptor(BridgeInterceptor())
// 3. CacheInterceptor(HTTP 缓存)
.addInterceptor(CacheInterceptor())
// 4. ConnectInterceptor(建立 TCP/TLS 连接)
.addInterceptor(ConnectInterceptor())
// 5. CallServerInterceptor(真正发请求)
.addInterceptor(CallServerInterceptor())
// 可选:你自己的拦截器(日志、Token 等)
.addInterceptor(LogInterceptor())
.build()
private val retrofit = Retrofit.Builder()
.baseUrl("https://api.xxx.com/")
.addCallAdapterFactory(DefaultCallAdapterFactory()) // CallAdapter 包装成协程挂起函数
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
val apiService = retrofit.create(ApiService::class.java)
}
ConverterFactory 数据解析工厂(必须)
- GsonConverterFactory(最常用)
- JacksonConverterFactory
- MoshiConverterFactory(谷歌推荐)
- ScalarsConverterFactory(返回 String / 基本类型)
- ProtoConverterFactory(Protocol Buffers)
CallAdapterFactory 回调适配工厂(根据需求加)
负责:把默认的 Call<T> 转成你想要的返回值类型
- LiveDataCallAdapterFactory(返回 LiveData)
- FlowCallAdapterFactory(返回 Kotlin Flow)
DefaultCallAdapterFactory(内置,支持 suspend)RxJava3CallAdapterFactory(返回 Observable / Flowable)CoroutinesCallAdapterFactory(老版协程用)
3. create 方法内部:反射创建动态代理,生成一个接口的实现类对象
public <T> T create(final Class<T> service) {
return (T) Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[]{service},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
// 4. 解析方法上的注解:@GET、参数…
Request request = parseAnnotations(method, args);
// 5. 创建 OkHttp Call
okhttp3.Call okCall = okHttpClient.newCall(request);
// 6. 返回 Retrofit 的 Call
return new Call<>(okCall, converterFactory);
}
}
);
}
7.调用 call.enqueue() 异步请求,OkHttp 在子线程发请求,拿到 Response 原始字符串
8.Converter 把 ResponseBody (Json)转成对象
真正调用的地方(Activity / ViewModel 里)
lifecycleScope.launch {
val userInfo = RetrofitManager.apiService.getUserInfo()
// 拿到数据,更新 UI
}
OkHttp 拦截器
重试 → 桥接 → 缓存 → 连接 → 请求
场景
你是一个买家(调用方),在网上买了一个快递(网络请求)。快递员(OkHttp)要把货从 ** 服务器(电商仓库)** 送到你手上。
1. RetryAndFollowUpInterceptor(重试与重定向拦截器)
OkHttp 的第一个拦截器,负责请求重试(如网络波动导致的请求失败)和重定向处理(服务器返回 3xx 状态码时,自动跳转到新的 URL 重新请求)。
职责:如果快递丢了、地址错了、货被退回了,他负责重新发货、纠正地址、重新投递。保证你的快递不轻易丢件。
比喻台词:“哎?快递没送到?地址填错了?我来帮你改地址!网络断了?我再试一次!302 重定向?我自动跳转到新地址继续送!”
2. BridgeInterceptor (桥梁 / 补全)—— 菜鸟驿站(补全规范)
职责:你只写了 “我要一个包裹”,驿站帮你补全成标准的快递单。
- 补上你没写的 寄件人信息、收件人电话、包装要求。
- 处理 运费、打包、贴纸。
- Cookie 就相当于:驿站帮你把你的会员积分卡贴在快递单上,证明你是 VIP。
核心区别:它只负责把你的零散需求,补成符合物流规则的标准单子。它不负责把货存起来,也不负责把货直接给你。
比喻台词:“客官,你只说了买手机,没写电话?我帮你补上!你的 VIP 卡?我帮你贴到快递单上!好嘞,标准快递单生成完毕,交给下一站!”
3. CacheInterceptor (缓存)—— 自家冰箱(真正的缓存)
职责:这是离你最近的地方。快递员先看一眼 你家冰箱 里有没有货。
- 如果冰箱里有,而且还没坏(缓存有效),直接从冰箱拿给你,根本不用去仓库。
- 冰箱没有,才去下一站。
核心区别:它管的是 **“货” 本身 **。
- BridgeInterceptor 管的是 “单”。
- CacheInterceptor 管的是 “货”。
比喻台词:“等一下!我刚发现你家冰箱里还有上次买的可乐,没过期!直接拿给你,不用去超市买了!省了一趟路,省了钱!”
4. ConnectInterceptor(连接) —— 修路工 + 打通高速路
职责:冰箱里没货,需要去仓库拿货。ConnectInterceptor 负责把你家到仓库的路修好。
- 修 TCP 高速路,打通隧道(TLS 加密)。
- 检查路况,保证路是通的。
比喻台词:“路不通怎么去仓库?我来修路!把高速公路打通,货车才能开过去!”
- 在责任链中执行
- 调用 ConnectionPool 连接池,获取一个可用连接
- 找不到就新建连接
- 把连接交给下一层CallServerInterceptor去发请求
- 它不存连接,只是使用者
ConnectionPool 连接池——“出租车复用,不是每次都新车”
- 以前的网络请求:建连接 → 请求 → 断开
- 每次都建连接很慢(握手耗时)
- OkHttp 连接池:建一次,反复用
- 5 分钟内再来请求,直接用老连接
- 多线程并发拿连接时,CAS + 无锁设计
- 用
Deque<RealConnection>双端队列存连接 - 对队列的并发修改没有用 synchronized
- 用
AtomicInteger做线程状态标记 - 清理空闲连接时用 CAS 自旋 避免锁竞争
5. CallServerInterceptor(请求服务器) —— 货车司机 + 搬运工
职责:路修好了,真正的货车司机。他负责开着车去仓库,把货买回来,并且亲手交到你手上。这是最后一步,也是真正完成交易的人。
比喻台词:“路通了!我去仓库提货!货到了!亲手交给你!交易完成!”
更多推荐




所有评论(0)