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 数据解析工厂(必须)

  1. GsonConverterFactory(最常用)
  2. JacksonConverterFactory
  3. MoshiConverterFactory(谷歌推荐)
  4. ScalarsConverterFactory(返回 String / 基本类型)
  5. ProtoConverterFactory(Protocol Buffers)

CallAdapterFactory 回调适配工厂(根据需求加)

    负责:把默认的 Call<T> 转成你想要的返回值类型

  1. LiveDataCallAdapterFactory(返回 LiveData)
  2. FlowCallAdapterFactory(返回 Kotlin Flow)
  3. DefaultCallAdapterFactory(内置,支持 suspend)
  4. RxJava3CallAdapterFactory(返回 Observable / Flowable)
  5. 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 + 无锁设计   
  1. Deque<RealConnection> 双端队列存连接
  2. 对队列的并发修改没有用 synchronized
  3. AtomicInteger 做线程状态标记
  4. 清理空闲连接时用 CAS 自旋 避免锁竞争

5. CallServerInterceptor(请求服务器) —— 货车司机 + 搬运工

职责:路修好了,真正的货车司机。他负责开着车去仓库把货买回来,并且亲手交到你手上。这是最后一步,也是真正完成交易的人。

比喻台词:“路通了!我去仓库提货!货到了!亲手交给你!交易完成!”

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐