• 面试:OkHttp相关


    Q:相关代码解析博客:

    什么,还有这么简单的OkHttp源码分析? - 掘金

    OkHttp解析(二)网络连接 - 简书 

    (面试必备-源码系列)OkHttp3 - 简书 

    OKHTTP之缓存配置详解_frank909的博客-CSDN博客_okhttp缓存 

    【知识点】OkHttp 原理 8 连问 - 掘金 

    Q:责任链的各个节点拦截器的作用:

    面试官:听说你熟悉OkHttp原理? - 掘金

    拦截器作用
    应用拦截器拿到的是原始请求,可以添加一些自定义header、通用参数、参数加密、网关接入等等。
    RetryAndFollowUpInterceptor处理错误重试和重定向
    BridgeInterceptor应用层和网络层的桥接拦截器,主要工作是为请求添加cookie、添加固定的header,比如Host、Content-Length、Content-Type、User-Agent等等,然后保存响应结果的cookie,如果响应使用gzip压缩过,则还需要进行解压。
    CacheInterceptor缓存拦截器,如果命中缓存则不会发起网络请求。
    ConnectInterceptor连接拦截器,内部会维护一个连接池,负责连接复用、创建连接(三次握手等等)、释放连接以及创建连接上的socket流。
    networkInterceptors(网络拦截器)用户自定义拦截器,通常用于监控网络层的数据传输。
    CallServerInterceptor请求拦截器,在前置准备工作完成后,真正发起了网络请求。

    Q:重试和失败重定向拦截器 -- RetryAndFollowUpInterceptor

    Android OkhttpInterceptor 笔记:RetryAndFollowUpInterceptor - 简书

    RetryAndFollowUpInterceptor 流程提炼如下:

    1、请求正常返回:网络获取到response并传递给下一级拦截器,然后没有其他情况 ,followUpRequest==null 就返回response;

    2、需要重定向:若返回需要重定向,也就是拿新的Request去获取Response,当然这里有一个最大重定向次数限制20次

    3、发生异常且需要恢复:①判断 OkHttpClient 是否支持失败重连的机制;
    如果不支持重连,就表示请求失败就失败了,不能再重试了;②协议错误、中断异常、SSL握手错误、certificate pinning错误

    Q :桥接和适配拦截器 -- BridgeInterceptor

    Android OkhttpInterceptor 笔记:BridgeInterceptor - 简书

    BridgeInterceptor是一个处理请求与返回的拦截器,它会对请求的Header进行一些处理,然后将工作交到下一级Interceptor,下一级完成后,再对返回进行处理

    BridgeInterceptor 流程提炼如下:

    1、是负责将我们构建的一个 Request 请求转化为能够进行网络访问的请求。
    2、将这个符合网络请求的 Request 进行网络请求。
    3、将网络请求回来的响应 Response 转化为用户可用的 Response。

    header的添加、处理字段如下:

    请求:Content-Type、Content-Length、Host、Accept-Encoding、Cookie、User-Agent
    响应:判断服务器是否支持gzip压缩,如果支持,则将压缩提交给Okio库来处理

    Q:网络缓存拦截器 -- CacheInterceptor

    Android 笔记: OkhttpInterceptor CacheInterceptor - 简书

    CacheInterceptor是okhttp中缓存拦截器,是负责http请求的缓存处理

    CacheInterceptor 流程如下: 

    1. 读取候选缓存,
    2. 创建缓存策略,强制缓存、对比缓存等
    3. 根据策略,如果不进行网络请求,而且没有缓存数据时,报错返回错误码 504。
    4. 根据策略,如果不进行网络请求,缓存数据可用,则直接返回缓存数据。
    5. 前面两个都没有返回,缓存无效,则继续执行网络请求,继续执行下一个Interceptor,即ConnectInterceptor。
    6. 接收到网络结果,缓存数据可以使用(返回 304),如果响应code式304,则使用缓存,返回缓存结果。
    7. 读取网络结果。
    8. 对数据进行缓存。
    9. 读取网络结果,构造 response,返回网络读取的结果。

    Q:网络缓存拦截器 -- ConnectInterceptor

    OKHTTP拦截器ConnectInterceptor的简单分析 - 简书

    Android OkhttpInterceptor 笔记:ConnectInterceptor - 简书

    ConnectInterceptor主要负责打开TCP链接、TLS握手。这里面把连接建立起来了,同时新建了一个编解码的类。

    ConnectInterceptor 流程如下: 

    1、在RetryAndFollowUpInterceptor中创建的StreamAllocation对象是真正负责socket连接的。

    2、执行StreamAllocation对象的 newStream() 方法创建HttpCodec,用于处理编码Request和解码Response;

    3、获取健康可用的连接findHealthyConnection

    4、findConnection真正去获取一个连接并且通过 SOCKET 建立连接;

    找到一个可用的连接,涉及到一些连接池的操作:

    • 如果没找到,那就新建一个连接。
    • 如果是普通的http请求,会使用Socket进行连接
    • 如果是https,会进行相应的握手,建立通道的操作。

    5、StreamAllocation对象的 connection() 方法获取到RealConnection对象,这个RealConnection对象是用来进行实际的网络IO传输的。

    Q:OkHttp发送、响应请求--CallServerInterceptor

    Android OkhttpInterceptor 笔记:CallServerInterceptor - 简书

    OKHTTP拦截器CallServerInterceptor的简单分析 - 简书

    Okhttp之CallServerInterceptor简单分析_郭梧悠的博客-CSDN博客_callserverinterceptor

    该拦截器前面的拦截器ConnectInterceptor主要负责打开TCP链接。而CallServerInterceptor的主要功能就是向服务器发送请求,并最终返回Response对象供客户端使用。
    1、获取HttpCodec对象,对<=Http1.1之前的或者http/2不同协议的http请求处理。
    2、发送http请求数据,构建Resposne.Builder对象,然后构建Response并返回

    CallServerInterceptor 流程如下: 

    1、获取几个前面已经创建的重要类(httpCodec, streamAllocation, request);

    2、先向sink(OutputStream)中写头信息(sink, 在创建连接时候已经创建好);

    3、判断是否有请求体,如有,走4,5的操作,没有直接到6;

    4、若头部添加了"100-continue", 相对于一次见到的握手操作,只有拿到服务的结果再继续;

    5、当“100-continue”成功或者不需要这个简单握手的,写入请求实体;

    6、finishRequest( 实际是调用了 sink.flush(), 来刷数据 )

    7、读取头部信息(通过source(InputStream), 读取头部信息,状态码等)

    8、构建Response, 写入原请求,握手情况,请求时间,得到的结果时间

    9、通过Response 状态码判断以及是否webSocket判断,是否返回一个空的body, 或者读取Body信息(通过 source(InputStream) 读取);

    10、读取到请求时的连接close ,或者服务器返回的 close, 进行断开操作;

    11、对于204,205的特殊状态码进行处理。
     

    简略回答: 

    OKHTTP拦截器CallServerInterceptor的简单分析 - 简书

    1、写入请求头信息,发送RequestHeader;

    2、有请求体的情况下,写入请求体信息,发送RequestBody;

    3、结束请求

    4、读取响应头信息,接收ResponseHeader,接收ResponseBody。

    Q:OKhttp连接池相关 -- ConnectInterceptor

    ConnectInterceptor主要负责打开TCP链接、TLS握手

    okhttp连接池复用机制_tangjiean的专栏-CSDN博客_okhttp连接池

    okhttp连接池复用机制_tangjiean的博客-CSDN博客_okhttp 连接池的复用如果保证连接的有效性 

    工作很简单,就是先尝试重用连接,如果没法重用就从连接池中取一个连接,如果没取到就创建新的连接。

    • 尝试重用连接
    • 尝试从池中获取连接
    • 创建一个新的连接
    • 连接服务器
    • 添加到连接池中

    Q:addInterceptor与addNetworkInterceptor的区别

    二者通常的叫法为应用拦截器和网络拦截器,从整个责任链路来看,应用拦截器是最先执行的拦截器,也就是用户自己设置request属性后的原始请求,而网络拦截器位于ConnectInterceptor和CallServerInterceptor之间,此时网络链路已经准备好,只等待发送请求数据。

    1. 首先,应用拦截器在RetryAndFollowUpInterceptor和CacheInterceptor之前,所以一旦发生错误重试或者网络重定向,网络拦截器可能执行多次,因为相当于进行了二次请求,但是应用拦截器永远只会触发一次。另外如果在CacheInterceptor中命中了缓存就不需要走网络请求了,因此会存在短路网络拦截器的情况。

    2. 其次,如上文提到除了CallServerInterceptor,每个拦截器都应该至少调用一次realChain.proceed方法。实际上在应用拦截器这层可以多次调用proceed方法(本地异常重试)或者不调用proceed方法(中断),但是网络拦截器这层连接已经准备好,可且仅可调用一次proceed方法。

    3. 最后,从使用场景看,应用拦截器因为只会调用一次,通常用于统计客户端的网络请求发起情况;而网络拦截器一次调用代表了一定会发起一次网络通信,因此通常可用于统计网络链路上传输的数据。

    Q:Okhttp如何开启的Http2.0--ConnectInterceptor

    Okhttp如何开启的Http2.0 - 腾讯云开发者社区-腾讯云

    只要后端将接口升级到Http2.0的支持之后,客户端就能自动的把所有的请求切换到Http2.0上,

    只要当前协议包含了HTTP_2,OKhttp就会开启Http2.0模式,否则则降级成1.1的代码。而如何去获取协议就是connectTls这个方法了

  • 相关阅读:
    KMP 算法
    dvwa命令执行漏洞分析
    静态代码块
    计算机毕业设计Java春之梦理发店管理源码+系统+数据库+lw文档
    OTSU分割算法
    序列解包和生成器表达式
    win10重命名文件夹找不到指定文件
    红队常用的防守策略.
    PRCV 2023 - Day3
    偏差数据比对
  • 原文地址:https://blog.csdn.net/cpcpcp123/article/details/127829814