OkHttp 中的 Interceptor 有哪几种类型?它们的执行顺序是怎样的?

解读

在国内一线/二线大厂的 Android 面试中,OkHttp 属于“简历写了网络库就必须深挖”的必考点。面试官抛出本题,核心想验证三点:

  1. 你是否真的阅读过 OkHttp 源码,还是只会“addInterceptor() 一把梭”;
  2. 能否区分“全局”与“单个请求”生效范围,避免线上出现 RetryAndFollowUp 死循环或 Cookie 重复注入;
  3. 是否具备“利用执行顺序做故障隔离”的架构思维,比如把日志拦截器放在 Application 层,把签名拦截器放在 Network 层,防止抓包工具绕开。

知识点

  1. 类型划分

    • Application Interceptor:通过 OkHttpClient.Builder.addInterceptor() 注册,位于 RetryAndFollowUp 逻辑之外,只会被调用一次,可拿到原始 Request 与最终 Response。
    • Network Interceptor:通过 OkHttpClient.Builder.addNetworkInterceptor() 注册,位于 RetryAndFollowUp、缓存、连接复用、重定向、重试等内部逻辑之后,每次重定向/重试都会被调用,可拿到中间态的 Response 与 Socket 层信息(如 IP、TLS 握手耗时)。
  2. 执行顺序(源码级)

    1. Application Interceptor 链(用户自定义)
    2. RetryAndFollowUpInterceptor(OkHttp 内部)
    3. BridgeInterceptor(补全缺省 Header、gzip、Cookie)
    4. CacheInterceptor(磁盘缓存策略)
    5. ConnectInterceptor(TCP + TLS 握手、连接池复用)
    6. Network Interceptor 链(用户自定义)
    7. CallServerInterceptor(写 RequestBody、读 ResponseBody)

    整体构成两条 RealInterceptorChain:先走“应用层链”,再走“网络层链”,中间由 RetryAndFollowUpInterceptor 负责循环调度。

  3. 国内实战注意

    • 抓包与合规:国内发布必须兼容国内厂商 ROM 的“网络访问合规检测”,把日志 Interceptor 放在 Application 层可避免触发多次检测。
    • 加密与防刷:把签名、时间戳、防重放放在 Network 层,可保证重试时自动更新签名,避免 401 重试风暴。
    • 业务隔离:Retrofit + Coroutine 场景下,若使用协程异常重试,需保证 Application Interceptor 不做强依赖 Response Count 的逻辑,否则会出现“只记录一次”的假象。

答案

OkHttp 的 Interceptor 按注册方式分为 Application Interceptor 与 Network Interceptor 两类。 执行顺序可概括为:Application Interceptor → RetryAndFollowUpInterceptor → BridgeInterceptor → CacheInterceptor → ConnectInterceptor → Network Interceptor → CallServerInterceptor。 Application 层只会执行一次,可获取最终响应;Network 层位于重试/重定向循环内部,每次网络 IO 都会经过,可获取中间响应与底层连接信息。

拓展思考

  1. 如何设计“双通道”隔离方案? 国内合规要求“日志不上公网”,可利用 Application Interceptor 把日志写入本地 mmap 文件,Network Interceptor 只负责上报加密后的埋点,二者互不干扰。

  2. 怎样避免“重试导致签名失效”? 把签名算法封装在 Network Interceptor 中,并依赖 Chain.connection().route() 的 socketAddress 做动态盐,保证每次重试都重新计算签名,防止网关把第一次 401 响应缓存下来。

  3. 与 Retrofit 的协程重试结合时,如何保持幂等? 在 Application 层做业务幂等键(如订单号),在 Network 层做网络幂等键(如 UUID + 时间戳),两层键值分离,可兼容业务方与网关的不同幂等策略。