OkHttp源码梳理
目录
一、基本使用
1 创建 OkHttpClient
2 构建请求 Request
3 创建和执行 Call
二、OkHttp请求整体流程
1. 用户调用入口
2. RealCall执行逻辑
2.1 同步请求:RealCall.execute()
2.2 异步请求:RealCall.enqueue(Callback)
3. Dispatcher调度请求
4. 拦截器链 getResponseWithInterceptorChain()
三、OkHttp 内置 Interceptor 总结
1. 重试与重定向拦截器(RetryAndFollowUpInterceptor)
2. 桥接拦截器(BridgeInterceptor)
3. 缓存拦截器(CacheInterceptor)
4. 连接拦截器(ConnectInterceptor)
5. 网络拦截器(CallServerInterceptor)
一、基本使用
1 创建 OkHttpClient
-
全局配置中心
-
可以通过
Builder
配置:-
连接超时、读写超时
-
连接池(ConnectionPool)
-
拦截器(Interceptor)
-
事件监听(EventListener)
-
代理设置、证书配置等
-
2 构建请求 Request
Request用于描述单次请求的参数信息,支持各种 HTTP 方法(GET、POST、PUT、DELETE...),也可以带 Header、Body。
3 创建和执行 Call
-
Call
是一次请求的抽象。 -
可以同步 (
execute
) 或异步 (enqueue
) 执行。 -
同步请求,会阻塞线程,不能直接在主线程当中调用
-
异步请求默认在子线程,自己切换线程。
二、OkHttp请求整体流程
1. 用户调用入口
无论是同步请求(execute()
),还是异步请求(enqueue()
),都是从RealCall开始的:
-
OkHttpClient.newCall(Request)
:返回一个RealCall
。 -
RealCall
是 OkHttp 处理每个请求的真正执行类。
2. RealCall
执行逻辑
2.1 同步请求:RealCall.execute()
2.2 异步请求:RealCall.enqueue(Callback)
-
okhttp会把异步请求包装成一个 AsyncCall
-
AsyncCall实现了Runnable接口,重写了run方法,并在run方法中调getResponseWithInterceptorChain()
3. Dispatcher调度请求
-
同步:直接加入
runningSyncCalls
。 -
异步:
-
先加入
readyAsyncCalls
等待排队, -
再调用promoteAndExecute()函数从异步任务等待队列选举任务并执行,选举时遍历等待队列,检查当前总请求数有没有达到上限,当前同一主机名请求数有没有达到上限,通过后交给线程池执行
-
最终都会执行 getResponseWithInterceptorChain()
,进入真正的拦截器链处理流程。
4. 拦截器链 getResponseWithInterceptorChain()
该方法会按一定的顺序构建拦截器列表interceptors
,接着利用interceptors
创建RealInterceptorChain
对象,该对象是一条责任链,使用了责任链模式。
请求从上往下交付,每个拦截器拿到请求都可以对请求做出相应处理,然后交给下一个拦截器,最后一个拦截器处理请求拿到响应后,将响应从下往上交付,每个拦截器拿到响应后再对响应做出相应处理,然后交给上一个拦截器。
拦截器 | 作用 |
---|---|
用户自定义应用拦截器 | 可以操作请求/响应,记录日志,加签名认证等 |
RetryAndFollowUpInterceptor | 负责失败重试、重定向 |
BridgeInterceptor | 请求标准化,响应标准化,添加必要头部,响应体解码 |
CacheInterceptor | 读取缓存,更新缓存 |
ConnectInterceptor | 建立与服务器的连接 |
用户自定义网络拦截器 | 观察实际请求/响应报文(仅对真正走网络的请求) |
CallServerInterceptor | 发送请求到服务器、接收响应 |
三、OkHttp 内置 Interceptor 总结
1. 重试与重定向拦截器(RetryAndFollowUpInterceptor)
- 作用:处理请求失败时的自动重试和 HTTP 重定向(如 302 跳转)。
- 关键行为:
- 检测可恢复的异常(如连接超时、Socket 断开)并重试请求。
- 遵循 HTTP 协议的重定向响应(如 301/302/307),自动跳转到新 URL。
- 限制最大重试次数(默认 20 次)和重定向次数。
- 示例场景:
// 当服务器返回 302 时,自动请求新的 Location 地址 Response response = client.newCall(request).execute(); // 无需手动处理跳转
2. 桥接拦截器(BridgeInterceptor)
- 作用:在应用代码和网络请求之间“桥接”,补充必要协议头并处理响应解码。
- 关键行为:
- 自动添加缺失的 HTTP 头(如
Host
、Content-Type
、Accept-Encoding: gzip
)。 - 处理
CookieJar
的自动注入(如果配置了 Cookie 管理器)。 - 解压 Gzip 压缩的响应体(透明解压,对应用层无感知)。
- 自动添加缺失的 HTTP 头(如
- 示例补充的请求头:
Accept-Encoding: gzip User-Agent: okhttp/4.10.0 Connection: keep-alive
3. 缓存拦截器(CacheInterceptor)
- 作用:根据 HTTP 缓存策略管理本地缓存,减少重复网络请求。
- 关键行为:
- 检查请求是否符合缓存条件(如
Cache-Control
头)。 - 返回缓存响应(如果未过期且有效)。
- 缓存服务器返回的新响应(如果配置了缓存目录)。
- 检查请求是否符合缓存条件(如
- 缓存配置示例:
OkHttpClient client = new OkHttpClient.Builder().cache(new Cache(new File("cacheDir"), 10 * 1024 * 1024)) // 10MB 缓存.build();
4. 连接拦截器(ConnectInterceptor)
- 作用:建立与目标服务器的 TCP/TLS 连接(或复用连接池中的连接)。
- 关键行为:
- 从连接池中复用空闲连接(减少 TCP 握手开销)。
- 必要时创建新连接(支持 HTTP/1.1、HTTP/2 或 WebSocket)。
- 处理 TLS 握手(HTTPS 请求)。
- 性能优化:
- 默认连接池最多维护 5 个空闲连接,存活时间 5 分钟。
5. 网络拦截器(CallServerInterceptor)
- 作用:最终向服务器发送请求数据并读取响应,完成网络 I/O 操作。
- 关键行为:
- 写入请求头和请求体(通过 Socket 输出流)。
- 读取响应头和响应体(通过 Socket 输入流)。
- 处理分块传输编码(
Transfer-Encoding: chunked
)。 - 关闭连接(如果未启用
keep-alive
)。
- 底层细节:
- 使用 Okio 库高效读写数据流。
相关文章:
OkHttp源码梳理
目录 一、基本使用 1 创建 OkHttpClient 2 构建请求 Request 3 创建和执行 Call 二、OkHttp请求整体流程 1. 用户调用入口 2. RealCall执行逻辑 2.1 同步请求:RealCall.execute() 2.2 异步请求:RealCall.enqueue(Callback) 3. Dispatcher调度请…...
【第三十三周】BLIP论文阅读笔记
BLIP 摘要Abstract文章信息引言方法MED预训练CapFilt 关键代码实验结果总结 摘要 本博客介绍了BLIP(Bootstrapping Language-Image Pre-training),这是一种创新的视觉-语言预训练框架,旨在通过统一模型架构和高效数据增强策略&am…...
如何配置osg编译使支持png图标加载显示
步骤如下: 1.下载osg代码 git clone https://github.com/openscenegraph/OpenSceneGraph.git cd OpenSceneGraph 2.开始配置编译 mkdir build cd build cmake … -DBUILD_OSG_PLUGINS_BY_DEFAULT1 -DBUILD_OSG_PLUGIN_PNG1 3.编译与安装 make make install 4.在安装…...
234. 回文链表(java)
个人理解: 1.先找到链表的中间节点,将链表分为前后两部分 方法:设置快慢指针,初始都指向头节点,慢指针每次走一步,快指针每次走两步。循环结束条件为:快指针后两个元素不为空,此时慢…...
面试:结构体默认是对齐的嘛?如何禁止对齐?
是的。 结构体默认是对齐的。结构体对齐是为了优化内存访问速度和减少CPU访问内存时的延迟。结构体对齐的规则如下: 某数据类型的变量存放的地址需要按有效对齐字节剩下的字节数可以被该数据类型所占字节数整除,char可以放在任意位置,int存…...
Leetcode837.新21点
目录 题目算法标签: 数学, 概率, 动态规划思路代码 题目 837. 新 21 点 算法标签: 数学, 概率, 动态规划 思路 定义状态表示为 f [ i ] f[i] f[i], 表示分数达到 i i i的时候的概率, 分析状态计算, 假设当前的分数是 i i i, 抽取到的牌得分数是 x x x, 那么当前状态就会转移…...
【C到Java的深度跃迁:从指针到对象,从过程到生态】第四模块·Java特性专精 —— 第十五章 泛型:类型系统的元编程革命
一、从C的void*到Java类型安全 1.1 C泛型的原始实现 C语言通过void*和宏模拟泛型,存在严重安全隐患: 典型泛型栈实现: #define DECLARE_STACK(type) \ struct stack_##type { \ type* data; \ int top; \ int capacity; \ }; #de…...
纯净无噪,智见未来——MAGI-1本地部署教程,自回归重塑数据本质
一、MAGI-1简介 MAGI-1 是一种逐块生成视频的自回归去噪模型,而非一次性生成完整视频。每个视频块(含 24 帧)通过整体去噪处理,当前块达到特定去噪阈值后,立即启动下一块的生成。这种流水线设计支持 最多 4 个块的并发…...
BG开发者日志0427:故事的起点
1、4月26日晚上,BG项目的gameplay部分开发完毕,后续是细节以及试玩版优化。 开发重心转移到story部分,目前刚开始, 确切地说以前是长期搁置状态,因为过去的四个月中gameplay部分优先开发。 --- 2、BG这个项目的起点…...
直播预告|TinyVue 组件库高级用法:定制你的企业级UI体系
TinyVue 是一个跨端跨框架的企业级 UI 组件库,基于 renderless 无渲染组件设计架构,实现了一套代码同时支持 Vue2 和 Vue3,支持 PC 和移动端,包含 100 多个功能丰富的精美组件,可帮助开发者高效开发 Web 应用。 4 月 …...
基于Jamba模型的天气预测实战
深入探索Mamba模型架构与应用 - 商品搜索 - 京东 DeepSeek大模型高性能核心技术与多模态融合开发 - 商品搜索 - 京东 由于大气运动极为复杂,影响天气的因素较多,而人们认识大气本身运动的能力极为有限,因此以前天气预报水平较低 。预报员在预…...
Customizing Materials Management with SAP ERP Operations
Customizing Materials Management with SAP ERP Operations...
使用 NServiceBus 在 .NET 中构建分布式系统
在 .NET 中,NServiceBus 依然是构建可靠、可扩展、异步消息驱动架构的强大工具。本文将为你讲解如何在 .NET 环境下集成 NServiceBus,帮助你理解其核心概念及配置方法,并快速上手构建基于消息的系统。 一、NServiceBus 简介 NServiceBus …...
【Linux网络与网络编程】13.五种 IO 模型
前言 在前面的学习中,有一个问题一直没有展开来说,即 IO 问题。 IO 到底有多少种方式呢?什么是高效的 IO 呢? IO 本质上就是 INPUT 和 OUTPUT 。在网络中 INPUT 就是从网卡中获取数据,而 OUTPUT 就是向网卡中发送数据…...
Java后端开发day37--源码解析:TreeMap可变参数--集合工具类:Collections
(以下内容全部来自上述课程) 1. TreeMap 1.1 须知 1.1.1 Entry 节点初始为黑色:提高代码阅读性 1.1.2 TreeMap中的成员变量 comparator:比较规则root:红黑树根节点的地址值size:集合的长度和红黑树…...
海关 瑞数 后缀分析 rs
声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 逆向过程 部分python代码 cp execj…...
【合新通信】---Mini单路光模块(Mini SFF/USOT)
产品特性 l 高可靠、全金属外壳、抗振动设计 l 紧凑的结构设计, 超小模块尺寸 l 可插拔标准LC单模光纤连接器接口,方便动态和灵活的配置数据连接 l 每通道工作速率可达1.25Gbps,速率可向下兼容 l 单路发射光纤通道,内置1310nm波长光发射…...
Java详解LeetCode 热题 100(02):LeetCode 49. 字母异位词分组(Group Anagrams)详解
文章目录 1. 题目描述2. 理解题目3. 解法一:排序法3.1 思路3.2 Java代码实现3.3 代码详解3.4 复杂度分析3.5 适用场景4. 解法二:计数法4.1 思路4.2 Java代码实现4.3 代码详解4.4 复杂度分析4.5 适用场景5. 解法三:字符串哈希法5.1 思路5.2 Java代码实现5.3 代码详解5.4 复杂…...
【每日随笔】文化属性 ① ( 天机 | 强势文化与弱势文化 | 文化属性的形成与改变 | 强势文化 具备的特点 )
文章目录 一、文化属性1、天机2、文化属性的强势文化与弱势文化强势文化弱势文化 二、文化属性的形成与改变1、文化属性形成2、文化属性改变3、文化知识的阶层 三、强势文化 具备的 特点 一、文化属性 1、天机 如果想要 了解这个世界的 底层架构 , 就需要掌握 洞察事物本质 的能…...
Java + Seleium4.X + TestNG自动化技术
系列文章目录 文章目录 系列文章目录前言一、 Java版Selenium自动化测试框架介绍和原理1.1 什么是Seleium1.2 特点1.3 注意点 二、安装SeleiumChrome环境 创建Maven项目2.1 安装Seleium Chrome环境2.2 Maven环境 三、Selenium4.X UI元素定位实战3.1 ID选择器3.2 Name选择器3.…...
Spark SQL核心概念与编程实战:从DataFrame到DataSet的结构化数据处理
一、Spark-SQL是什么 Spark SQL 是 Spark 用于结构化数据(structured data)处理的 Spark 模块。 二、Hive and SparkSQL SparkSQL 的前身是 Shark,Shark是给熟悉 RDBMS 但又不理解 MapReduce 的技术人员提供的快速上手的工具。 Hive 是早期唯一运行在 Hadoop 上的 S…...
electron-vite 应用打包自定义图标不显示问题
// 修改electron-builder.yml ... win:executableName: xxx //可执行文件名称icon: build/icon.ico //你的图标路径 ...打包后,自定义图标不显示原因: 1 cannot execute causeexit status 2,安装包无法生成 用管理员身份运行,win11右击开始…...
AI中Token的理解与使用总结
AI中Token的理解与使用总结 什么是Token 在AI领域,特别是自然语言处理(NLP)中,Token是指将文本分割成的最小处理单元。Tokenization(分词)是将原始文本分解为Token的过程。 Token的几种形式 单词级Token:以单词为基本单位 示例:“Hello world” → [“Hello”, “world”…...
C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 14)
🎁个人主页:工藤新一 🔍系列专栏:C面向对象(类和对象篇) 🌟心中的天空之城,终会照亮我前方的路 🎉欢迎大家点赞👍评论📝收藏⭐文章 文章目录 二…...
全栈量子跃迁:当Shor算法破解RSA时,我们如何用晶格密码重构数字世界的信任基岩?
一、量子威胁的降维打击 1. Shor算法的毁灭性力量 # Shor算法量子电路简化示例(Qiskit实现) from qiskit import QuantumCircuit from qiskit.circuit.library import QFTdef shor_circuit(n: int, a: int) -> QuantumCircuit:qc QuantumCircuit(2…...
python实战项目65:drissionpage采集boss直聘数据
python实战项目65:drissionpage采集boss直聘数据 一、需求简介二、流程分析三、完整代码一、需求简介 boss直聘网站近期改版,改版之后代码需要做相应的升级维护。drissionpage采集网页数据是一种不错的方式,笔者认为比Selenium好用,使用方法大家可以自行查阅资料。boss直聘…...
常用的性能提升手段--提纲
上一篇文章里,介绍了提升性能的一种优化手段:池化。 这篇文章来归纳整理一下其他的常见的提升性能的手段 1. 缓存 (Caching) 缓存可以说是计算机领域的万金油了,它无处不在。 举个最简单的例子,CPU -> L1,L2,L3 Cache -> 内存 。 CPU的处理速度要比内存快几个数量…...
天梯——现代战争
第一次做的时候,直接暴力,显然最后超时。 暴力代码如下: #include<bits/stdc.h> using namespace std; const int N10005; bool mark1[N]{0},mark2[N]{0}; int p[N][N]; int main(){int n,m,k,a,b;cin>>n>>m>>k;fo…...
Codeforces Round 1021 (Div. 2) D. Baggage Claim(建图)
每周五篇博客:(4/5) https://codeforces.com/contest/2098/problem/D 题意 每个机场都有一个行李索赔区,巴尔贝索沃机场也不例外。在某个时候,Sheremetyevo的一位管理员提出了一个不寻常的想法:将行李索…...
常用第三方库:shared_preferences数据持久化
常用第三方库:shared_preferences数据持久化 前言 shared_preferences是Flutter中最常用的轻量级数据持久化解决方案,它提供了一个简单的key-value存储机制,适合存储用户配置、应用设置等小型数据。本文将从实战角度深入讲解shared_prefere…...
项目驱动 CAN-bus现场总线基础教程》随笔
阅读:《项目驱动 CAN-bus现场总线基础教程》 仲裁段的实现 有感而发 感觉出人意外之处 感觉出人意外之处 最近在阅读入门的CAN相关书籍时,在介绍仲裁段是如何实现各节点之间,通讯仲裁功能的章节中,有如下一段描述: …...
WPF之XAML基础
文章目录 XAML基础:深入理解WPF和UWP应用开发的核心语言1. XAML简介XAML与XML的关系 2. XAML语法基础元素语法属性语法集合语法附加属性 3. XAML命名空间命名空间映射关系 4. XAML标记扩展静态资源引用数据绑定相对资源引用常见标记扩展对比 5. XAML与代码的关系XAM…...
测试基础笔记第十四天
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、字符串1.字符串2.字符串切片3.查找find()4.去除两端空白字符 strip5.字符串转换大小写 lower、upper5.拆分 split()6.字符串的其他常见方…...
Java详解LeetCode 热题 100(01):LeetCode 1. 两数之和(Two Sum)详解
文章目录 1. 题目描述2. 理解题目3. 解法一:暴力枚举法3.1 思路3.2 Java代码实现3.3 代码详解3.4 复杂度分析3.5 适用场景 4. 解法二:哈希表法4.1 思路4.2 Java代码实现4.3 代码详解4.4 复杂度分析4.5 适用场景 5. 解法三:两遍哈希表法5.1 思…...
机器学习之三:归纳学习
正如人们有各种各样的学习方法一样,机器学习也有多种学习方法。若按学习时所用的方法进行分类,则机器学习可分为机械式学习、指导式学习、示例学习、类比学习、解释学习等。这是温斯顿在1977年提出的一种分类方法。 有关机器学习的基本概念,…...
AI声像融合守护幼儿安全——打骂/异常声音报警系统的智慧防护
幼儿园是孩子们快乐成长的摇篮,但打骂、哭闹或尖叫等异常事件可能打破这份宁静,威胁幼儿的身心安全。打骂/异常声音报警系统,依托尖端的AI声像融合技术,结合语音识别、情绪分析与视频行为检测,为幼儿园筑起一道智能安全…...
2024ICPC网络赛第二场题解
文章目录 F. Tourist(签到)I. Strange Binary(思维)J. Stacking of Goods(思维)A. Gambling on Choosing Regionals(签到)G. Game(数学)L. 502 Bad Gateway(数学)E. Escape(BFS)C. Prefix of Suffixes(kmp结论)K. match(01trie分治多项式乘法组合数) 题目链接 F. Tourist(签到…...
风控策略引擎架构设计全解析:构建智能实时决策系统
摘要 本文深入探讨现代风控策略引擎的核心架构设计,结合金融反欺诈、电商交易风控等典型场景,详细解析实时决策、规则引擎、特征计算等关键技术模块的实现方案。通过分层架构设计、分布式计算优化、策略动态编排等创新方法,展示如何构建支撑每秒万级决策的高可用风控系统。…...
TensorFlow 安装全攻略
选择 TensorFlow 的原因: TensorFlow 是一个端到端平台,它提供多个抽象级别,因此您可以根据自己的需求选择合适的级别。您可以使用高阶 Keras API 构建和训练模型,该 API 让您能够轻松地开始使用 TensorFlow 和机器学习。如果您需…...
Dijkstra 算法代码步骤[leetcode.743网络延迟时间]
有 n 个网络节点,标记为 1 到 n。 给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] (ui, vi, wi),其中 ui 是源节点,vi 是目标节点, wi 是一个信号从源节点传递到目标节点的时间。 现在,…...
Ubuntu22.04/24.04 P104-100 安装驱动和 CUDA Toolkit
硬件环境 使用一块技嘉 B85m-DS3H 安装 P104-100, CPU是带集成显卡的i5-4690. 先在BIOS中设置好显示设备优先使用集成显卡(IGX). 然后安装P104-100开机. 登入Ubuntu 后查看硬件信息, 检查P104-100是否已经被检测到 # PCI设备 lspci -v | grep -i nvidia lspci | grep NVIDIA …...
Golang 学习指南
目录 变量与常量数据类型与控制结构常用数据结构函数与错误处理指针与并发Gin 框架与 go mod小结与参考资料 1. 变量与常量 变量(var) 用于定义可变的值。可以指定类型,也可以自动推断类型。示例:var name string "Golang…...
Ubuntu 磁盘空间占用清理(宝塔)
目录 前言1. 基本知识2. 实战 前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 爬虫神器,无代码爬取,就来:bright.cn 本身自搭建了一个宝塔,突然一下子多了好些空…...
AntBio: 2025 AACR Meeting - Charting New Oncology Frontiers Together
AntBio cordially invites you to attend the 2025 AACR Annual Meeting and jointly chart a new course in oncology research! The global benchmark for cancer research and therapeutics—the 2025 American Association for Cancer Research (AACR) Annual Meeting—wi…...
数模学习:二,MATLAB的基本语法使用
注释代码: (1)在每行语句后面加上分号,则不显示该行代码的运算结果。 在每行代码前加%,则该行代码会被注释掉 (2) 多行注释: 选中要注释的多行语句,按快捷键Ctrl R (3) 取消注释: 选中要注释的多行语句…...
【Webpack \ Vite】多环境配置
环境变量脚本命令 如何通过不同的环境变量或不同的配置文件进行项目区分,动态加载配置。通常,使用环境变量是最简单且灵活的方法,因为它不需要改变构建命令或创建多个配置文件 环境变量 在根目录下创建 .env.xxx 文件,为不同的环…...
已知漏洞打补丁
. 打补丁 根据MS漏洞编号或者CVE漏洞编号都可以找到对应的HotfixID。 1.根据MS漏洞编号可以使用:https://learn.microsoft.com/zh-cn/security-updates/securitybulletins/securitybulletins 即可找到KB编号。 2.根据CVE漏洞编号可以使用:https://cve…...
WGS84(GPS)、火星坐标系(GCJ02)、百度地图(BD09)坐标系转换Java代码
在做基于百度地图、高德地图等电子地图做为地图服务的二次开发时,通常需要将具有WGS84等坐标的矢量数据(如行政区划、地名、河流、道路等GIS地理空间数据)添加到地图上面。 然而,在线地图大多使用的是火星坐标系,需要…...
R语言操作n
1.加载安装vegan包 2.查看data(varechem)和data(varespec),探索其维度和结构 3.基于varespec构建物种互作网络,输出gml文件并采用gephi可视化为图片,输出pdf,阈值为r>0.6,p<0.05 4.基于varespec和varechem构建物种-环境互作…...
ChatGPT与DeepSeek在科研论文撰写中的整体科研流程与案例解析
随着人工智能技术的快速发展,大语言模型如ChatGPT和DeepSeek在科研领域展现出强大的潜力,尤其是在论文撰写方面。本文旨在介绍如何利用ChatGPT和DeepSeek提升科研论文撰写的效率与质量,并提供一个具体案例,详细阐述其技术流程及公…...