OkHttp深度解析:请求流程、分发器机制、拦截器工作及TCP连接复用

目录

一、OkHttp请求的请求流程是怎样的?

二、OkHttp分发器是怎样工作的?

2.1 请求队列与线程池维护

2.2 异步请求处理

2.3 同步请求处理

2.4 请求执行

2.5 请求完成处理:

2.6 线程池设计

三、OkHttp拦截器是如何工作的?

四、应用拦截器和网络拦截器的区别?

4.1 调用顺序和位置

4.2 功能和用途

五、OkHttp 如何复用TCP 连接的?

5.1 具体过程

5.2 优势

相关推荐


一、OkHttp请求的请求流程是怎样的?

    public void sendOkHttp(){//创建OkHttpClient对象OkHttpClient client = new OkHttpClient();//创建RequestRequest request = new Request.Builder().url("https://shuaici.blog.csdn.net/").build();//创建Call对象client.newCall(request)Call call = client.newCall(request);//通过execute()方法获得请求响应的Response对象call.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {}@Overridepublic void onResponse(Call call, Response response) throws IOException {if(response.isSuccessful()){String result = response.body().string();//处理UI需要切换到UI线程处理}}});}

请求流程总结

  1. 创建OkHttpClient实例:OkHttpClient是OKHttp库的核心类,用于发送HTTP请求和接收HTTP响应。
  2. 创建Request对象:Request对象封装了HTTP请求的所有信息,包括URL、请求方法(GET、POST等)、请求头部和请求体等。
  3. 执行请求
    1. 通过 OkHttpClient 的 newCall 方法创建 Call 对象。这里的Call是一个接口,实际返回的是它的唯一实现子类RealCall对象。
    2. 同步请求:通过调用call.execute()方法真正发起网络请求,并返回一个Response对象。这种方法会阻塞当前线程,直到请求完成并返回响应。
    3. 异步请求:通过调用call.enqueue(callback)方法真正发起网络请求,并传入一个Callback对象。当请求完成时,OKHttp会自动调用Callback对象的onResponseonFailure方法来处理响应或错误。
  4. 处理响应:在获取到Response对象后,可以通过调用其方法(如body().string())来获取响应体的内容,并进行相应的处理。

二、OkHttp分发器是怎样工作的?

        OkHttp分发器(Dispatcher)的主要作用是调配请求任务,它内部维护了队列和线程池来管理请求的执行。以下是OKHttp分发器的工作机制:

2.1 请求队列与线程池维护

  • 分发器内部主要维护了两个队列:readyAsyncCalls(等待执行的异步请求队列)和runningAsyncCalls(正在执行的异步请求队列),以及runningSyncCalls(正在执行的同步请求队列)。
  • 分发器还包含一个线程池executorService,用于执行请求任务。

2.2 异步请求处理

  • 当发起异步请求时,分发器会检查:
  1. 同时请求的异步任务数不得大于64(maxRequests)和
  2. readyAsyncCalls队列中取出异步任务其Host,在runningAsyncCalls中不得大于5。
  3. 则将请求添加到runningAsyncCalls队列并立即执行;如果超过了,则将请求加入到readyAsyncCalls队列中等待。

2.3 同步请求处理

        对于同步请求,分发器仅记录请求(放入runningSyncCalls队列中),因为同步请求不需要线程池,也不存在并发限制,所以分发器仅做记录,后续按照加入队列的顺序同步请求即可。

2.4 请求执行

        请求执行是通过分发器将任务分配给拦截器链来完成的。拦截器链负责完成网络请求过程,包括请求重试、缓存处理、建立连接等一系列操作。

2.5 请求完成处理:

        请求完成后,分发器会runningAsyncCallsrunningSyncCalls队列中移除对应的请求,并检查是否有等待执行的请求,如果有,则将等待的请求加入到线程池执行

2.6 线程池设计

        分发器中的线程池设计为:核心线程数为0,最大线程数为Int.MAX_VALUE,空闲时间为60秒,工作队列为SynchronousQueue()。这种设计意味着,当有任务需要执行时,如果线程池中没有可用线程,会直接创建新线程来处理任务。

三、OkHttp拦截器是如何工作的?

        OKHttp的拦截器机制是其核心功能之一,它基于责任链模式实现。每个拦截器都可以处理请求或响应,并将请求或响应传递给下一个拦截器。拦截器的工作机制如下:

  1. 在发起HTTP请求时,OKHttp会依次调用每个拦截器的intercept()方法,将请求传递给下一个拦截器,直到请求被发送到服务器或被拦截器拦截并返回响应为止。
  2. 在接收到响应后,OKHttp会依次调用每个拦截器的intercept()方法,将响应传递给下一个拦截器,直到响应被处理完毕或被拦截器拦截并返回新的响应为止。
  3. 拦截器在处理请求和响应时,可以通过Request和Response对象来获取和修改请求和响应的信息。
/*** 获取响应的拦截器链。* * @return Response 对象,包含服务器的响应。* @throws IOException 如果发生 I/O 错误。*/
Response getResponseWithInterceptorChain() throws IOException {// 构建完整的拦截器栈。List<Interceptor> interceptors = new ArrayList<>();// 1. 应用拦截器:用户自定义的拦截器,可以在此拦截器中添加自定义逻辑。interceptors.addAll(client.interceptors()); // 2. 重试重定向拦截器:处理请求重试和重定向逻辑。interceptors.add(new RetryAndFollowUpInterceptor(client)); // 3. 桥接拦截器:处理请求和响应的转换,例如将请求转换为HTTP/2请求。interceptors.add(new BridgeInterceptor(client.cookieJar())); // 4. 缓存拦截器:处理缓存逻辑,决定是否从缓存中读取响应或将响应存储到缓存中。interceptors.add(new CacheInterceptor(client.internalCache())); // 5. 连接拦截器:处理与服务器建立连接的逻辑,包括DNS解析和TLS握手。interceptors.add(new ConnectInterceptor(client)); // 如果不是WebSocket请求,添加网络拦截器。if (!forWebSocket) {// 6. 网络拦截器:用户自定义的网络层面的拦截器,可以在此拦截器中添加网络层面的自定义逻辑。interceptors.addAll(client.networkInterceptors()); }// 7. 服务器调用拦截器:实际向服务器发送请求并接收响应的拦截器,如果是WebSocket请求则特殊处理。interceptors.add(new CallServerInterceptor(forWebSocket)); // ......
}

四、应用拦截器和网络拦截器的区别?

4.1 调用顺序和位置

  • 应用拦截器:先经过应用拦截器,再进入内核,再进入网络拦截器。应用拦截器只关心发起的请求和最终得到的结果,不关心重定向或重试等中间响应。
  • 网络拦截器:可以操作重定向或重试的中间响应。如果应用拦截器决定短路并以缓存返回,则网络拦截器就得不到调用

4.2 功能和用途

  • 应用拦截器:常用于日志记录、身份验证、修改请求或响应等操作。它们可以拦截Chain.proceed()或多次调用Chain.proceed()。
  • 网络拦截器:更侧重于网络层面的操作,如处理重定向、重试策略等。

五、OkHttp 如何复用TCP 连接的?

        OkHttp通过其内置的连接池机制高效地复用了TCP连接。连接池会维护一组已经建立的TCP连接,并在需要发送新的HTTP请求时重用这些连接,而不是每次请求都重新建立一个新的TCP连接。

5.1 具体过程

  1. 检查连接池:当OkHttp需要发送一个新的HTTP请求时,它首先会检查连接池中是否有可用的TCP连接。这个检查过程是基于目标服务器的IP地址和端口来进行的。
  2. 复用连接:如果连接池中存在与目标服务器匹配的可用TCP连接,OkHttp就会复用该连接来发送HTTP请求。这意味着,同一个TCP连接上可以发送多个HTTP请求和接收相应的响应,从而减少了每次请求时建立新连接的开销。
  3. 管理连接生命周期:OkHttp会根据配置的参数(如最大空闲连接数、连接空闲超时等)自动管理连接池中的连接。如果某个连接在一段时间内没有被使用,OkHttp会自动将其关闭,以释放系统资源。

5.2 优势

  1. 提高性能:通过复用TCP连接,OkHttp显著减少了连接建立和关闭的开销,从而提高了HTTP请求的响应速度和整体性能。
  2. 减少资源消耗:复用连接可以减少系统资源的消耗,尤其是在高并发的情况下,能够有效减轻服务器的负担。
  3. 降低网络延迟:已经建立的TCP连接可以直接用于发送新的HTTP请求,无需重新进行TCP三次握手等操作,从而降低了网络延迟。

相关推荐

Android OkHttp使用和源码详解-CSDN博客文章浏览阅读1.5k次,点赞10次,收藏5次。OkHttp 是一套处理 HTTP 网络请求的依赖库,由 Square 公司设计研发并开源,目前可以在 Java 和 Kotlin 中使用。对于 Android App 来说,OkHttp 现在几乎已经占据了所有的网络请求操作,RetroFit + OkHttp 实现网络请求似乎成了一种标配。因此它也是每一个 Android 开发工程师的必备技能,了解其内部实现原理可以更好地进行功能扩展、封装以及优化。_com.squareup.okiohttps://shuaici.blog.csdn.net/article/details/120174041Android OkHttp+Retrofit+Rxjava+Hilt实现网络请求框架-CSDN博客文章浏览阅读3.6k次,点赞37次,收藏47次。本文通过OkHttp+Retrofit+Rxjava+Hilt实现一个网络请求框。 最终代码特别省事。_android response.body().getdata()https://shuaici.blog.csdn.net/article/details/121384534

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/65808.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云计算课程报告实验-WordCount算法实验 过程记录

内容描述 本实验指导书通过在华为鲲鹏上&#xff0c;编译运行WordCount程序。完成实验操作后&#xff0c;读者会掌握简单的程序编写&#xff0c;如WordCount中的getWords、countWords、treeMerge。 实验环境 华为鲲鹏云主机、openEuler 20.03操作系统&#xff1b;安装mpich-3…

2018年全国硕士研究生入学统一考试管理类专业学位联考英语(二)试题-纯享题目版

&#x1f3e0;个人主页&#xff1a;fo安方的博客✨ &#x1f482;个人简历&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;目前中南大学MBA在读&#xff0c;也考取过HCIE Cloud Computing、CCIE Security、PMP、CISP、RHCE、CCNP RS、PEST 3等证书。&#x1f433; &…

kafka使用常见问题

连接不上kafka,报下边的错 org.apache.kafka.common.KafkaException: Producer is closed forcefully.at org.apache.kafka.clients.producer.internals.RecordAccumulator.abortBatches(RecordAccumulator.java:760) [kafka-clients-3.0.2.jar:na]at org.apache.kafka.client…

Jenkins(持续集成与自动化部署)

Jenkins 是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具。 官网&#xff1a;https://www.jenkins.io/ GitLab安装使用 安装前提&#xff1a;内存至少需要4G 官方网站&#xff1a;https://about.gitlab.com/ 安装文档&#xff1a;https://docs.gitlab.c…

MyBatis执行一条sql语句的流程(源码解析)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 MyBatis执行一条sql语句的流程&#xff08;源码解析&#xff09; MyBatis执行sql语句的流程加载配置文件加载配置文件的流程 创建sqlsessionFactory对象解析Mapper创建sqlses…

【C++】探索C++11中的范围for循环与auto关键字

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;1. 范围for循环的基础用法1.1 什么是范围for循环&#xff1f;1.2 示例代码代码解析 1.3 范围for的特点传统for循环与范围for循环对比 1.4 使用引用修改元素 &#x1f4af;2…

mac下载Homebrew安装nvm

通过Homebrew安装 - 国内下载地址 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"安装nvm brew install nvm 配置nvm环境变量 export NVM_DIR“$HOME/.nvm” [ -s “/usr/local/opt/nvm/nvm.sh” ] && . “/usr/…

解決當前IP地址僅適用於本地網路

想要解決“當前IP地址僅適用於本地網路”其實並不困難。本篇文章將介紹其發生的原因以及如何解決。 “僅限本地網路”是什麼意思&#xff1f; 當IP地址為“僅限本地網路”時&#xff0c;意味著設備正在使用私人網路內部IP地址&#xff0c;但無法連接到互聯網。如果將本地IP視…

HANA数据库 XS 503 Service not available

http_url配置正确 在将单个数据库系统转换为多租户数据库容器系统之后&#xff0c;无法通过URL访问新租户数据库的独立XS引擎服务。调用相应的URL会产生这样的错误&#xff1a;503服务不可用 Solution &#xff08;启用租户数据库引擎的嵌套模式&#xff08;HDD不用&#xff…

【大模型实战篇】Mac本地部署RAGFlow的踩坑史

1. 题外话 最近一篇文章还是在11月30日写的&#xff0c;好长时间没有打卡了。最近工作上的事情特别多&#xff0c;主要聚焦在大模型的预训练、微调和RAG两个方面。主要用到的框架是Megatron-DeepSpeed&#xff0c;后续会带来一些分享。今天的文章主要聚焦在RAG。 近期调研了一系…

推荐5款局域网IP扫描工具,支持电脑+Android!

在日常网络管理中&#xff0c;快速扫描局域网中的设备和IP地址是一项基本但非常重要的任务。无论是排查网络问题还是进行设备管理&#xff0c;一款好用的 IP 扫描工具都能让你事半功倍。 如何选择适合自己需求的局域网 IP 扫描工具&#xff1f;有哪些功能强大又易于上手的工具…

python修改ppt中的文字部分及插入图片

批量修改ppt中的某个模块&#xff0c;或者批量制作奖状等场景会用到&#xff1b; import os import pandas as pd from pptx import Presentation from pptx.util import Inchesfilepath/Users/kangyongqing/Documents/kangyq/202303/分析模版/批量制作/file1时段预警_副本.pp…

计算机网络—————考研复试

第一章、计算机网络体系结构 1. OSI参考模型和TCP/IP模型&#xff1a; OSI与TCP/IP的记忆方法&#xff1a;只需把OSI的七层记住&#xff0c;将应用层、表示层、会话层一起记&#xff0c;到TCP/IP变成应用层。物理层和数据链路层换成网络接口层。把网络层换个字变成网际层。 而…

springboot534售楼管理系统(论文+源码)_kaic

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本售楼管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&am…

计算机体系结构期末复习3:GPU架构及控制流问题

目录 一、GPU设计思路 1.简化流水线、增加核数 2.单指令多线程&#xff08;SIMT&#xff09; 3.同时驻留大量线程 4.总思路&#xff1a;多线程单指令多线程 二、GPU的控制流问题 1.什么是控制流问题 2.怎么应对分支分歧 一、GPU设计思路 1.简化流水线、增加核数 2.单指…

[实用指南]如何将视频从iPhone传输到iPad

概括 将视频从 iPhone 传输到 iPad 时遇到问题&#xff1f;您可能知道一种方法&#xff0c;但不知道如何操作。此外&#xff0c;您要传输的视频越大&#xff0c;完成任务就越困难。那么如何将视频从 iPhone 传输到 iPad&#xff0c;特别是当您需要发送大视频文件时&#xff1f…

httpslocalhostindex 配置的nginx,一刷新就报404了

当你的Nginx配置导致页面刷新时报404错误时&#xff0c;通常是由于以下几个原因造成的&#xff1a; 静态文件路径配置错误&#xff1a;Nginx没有正确地指向静态文件的目录。前端路由问题&#xff1a;如果是SPA&#xff08;单页应用&#xff09;&#xff0c;刷新页面时Nginx没有…

药片(药丸)和胶囊识别数据集,使用yolo,pasical voc xml, coco json格式标注,可识别药片和胶囊两种标签,2445张原始图片

药片(药丸)和胶囊识别数据集&#xff0c;使用yolo&#xff0c;pasical voc xml, coco json格式标注&#xff0c;可识别药片和胶囊两种标签&#xff0c;2445张原始图片 数据集分割 训练组80&#xff05; 1967图片 有效集13% 317图片 测试集7% 161图片 预处…

解决winform中comboBox下拉不够长的问题

默认情况下的combobox 可以看到comboBox不够长 导致信息显示不完成 解决方法 修改属性&#xff1a;DropDownWidth为308 修改前修改后

HTML——43.创建表格

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表格</title></head><body><!--table标签用来定义表格&#xff0c;border属性表示边框--><!--tr标签表示表格中的一行--><!--th标签表示表…