OkHttp
文章目录
- OkHttp
- 概要
- 1.简介
- 2.特点
- 3.基本组成
- 5.工作流程
- 拦截器
- 1.简介
- 2.内置拦截器
- 3.自定义拦截器
- 连接池
- 1.简介
- 2.常用参数配置选项
- Dispatcher和线程池
- 1.简介
- 2.重要方法
- 3.DispatCher中的双端队列
- 4.总结
OkHttp
概要
1.简介
- OkHttp是一个开源的HTTP客户端,用于在Java和Android应用程序中发送HTTP请求。
- 是一个支持 HTTP 和 HTTP/2 的封装的网络请求客户端。
2.特点
- 高效的连接复用:OkHttp可以复用现有的TCP连接,减少建立和关闭连接的开销,提高性能。
- 支持HTTP/2:OkHttp支持最新的HTTP/2协议,能够提高传输速度和减少延迟。
- 灵活的配置:用户可以配置各种请求参数,如超时时间、重定向策略、缓存策略等。
- 强大的拦截器机制:通过拦截器,可以在请求发送和响应接收的过程中插入自定义逻辑,非常适合进行日志记录、添加认证等操作。
- 简单的API:OkHttp提供了简单易用的API,使得发送请求和处理响应变得十分方便。
- 支持同步和异步请求:用户可以选择同步或异步地发送HTTP请求,以适应不同的应用场景。
3.基本组成
-
请求(Request)和响应(Response):
OkHttp中的每个请求和响应都封装了HTTP协议的所有必要信息,包括方法(如GET、POST)、URL、头部(Headers)、正文(Body)等。 -
客户端(Client):
客户端是OkHttp的核心,负责创建请求、管理连接、执行请求并处理响应。它提供了多种配置选项,如超时时间、重定向策略、协议版本等。 -
连接管理器(ConnectionPool):
连接管理器负责维护一个连接池,用于复用TCP连接。这样可以减少建立和关闭连接的次数,提高性能。 -
拦截器(Interceptor):
拦截器是一个可以在请求发送到服务器之前和响应从服务器返回之后修改请求或响应的组件。它们通常用于添加认证、日志记录、请求头修改等。 -
事件日志(EventListener):
事件日志用于记录请求和响应的生命周期事件,如连接创建、响应接收等。这有助于调试和监控网络活动。
同步/异步执行:
OkHttp支持同步和异步执行请求。同步请求会阻塞当前线程直到请求完成,而异步请求则使用回调在后台线程中处理结果。 -
缓存(Cache):
OkHttp支持HTTP缓存,可以缓存响应以供后续请求重用,减少网络延迟和数据量传输。 -
协议解析器(Protocols):
OkHttp支持多种HTTP协议版本,如HTTP/1.1和HTTP/2。协议解析器负责解析传入的网络数据,并将其转换为可处理的响应对象。 -
SSL/TLS加密:
OkHttp支持通过SSL/TLS对网络连接进行加密,以确保数据传输的安全性。 -
错误处理:
OkHttp提供了错误处理机制,能够处理网络问题、超时、解析错误等各种异常情况。OkHttp 主要是通过 5 个拦截器和 3 个双端队列(2 个异步队列,1 个同步队列)工作。
内部实现通过一个责任链模式完成,将网络请求的各个阶段封装到各个链条中,实现了各层的解耦。
底层通过 Socket 发送 HTTP 请求与接受响应,并实现了连接池的概念。
5.工作流程
-
通过构建者构建出OkHttpClient对象,通过newCall方法获得RealCall请求对象,发起同步或异步请求。
-
通过Dispatcher对我们所有的RealCall(Call的具体实现类)进行统一管理,处理同步或异步请求。
-
通过拦截器对请求依次处理,与服务的建立连接后,获取返回数据,再经过上述拦截器依次处理,最后将结果返回给调用方。
拦截器
1.简介
- 允许开发者在请求发送到服务器之前和响应从服务器返回之后对请求或响应进行修改。
- 五个内置拦截器按顺序组成一个拦截器链,每个拦截器都可以选择处理请求或响应,或者传递给下一个拦截器。
- 此外,开发者还可以自定义拦截器,插入到这个拦截器链中的适当位置,以便能够处理请求或响应的相应部分。
2.内置拦截器
- RetryAndFollowUpInterceptor:
这个拦截器负责处理重定向和重新尝试逻辑。如果原始请求因为某些原因(如网络问题)失败了,它会尝试再次发送请求。此外,如果服务器响应了一个重定向,这个拦截器也会处理后续的请求。 - CacheInterceptor:
缓存拦截器负责处理HTTP缓存。在发送实际的网络请求之前,它会检查本地缓存是否有响应的副本,如果有,则返回缓存版本而不是发起网络请求。同样,当响应被返回时,它会将响应缓存到本地。 - ConnectInterceptor:
连接拦截器在建立连接时被调用。它负责创建和管理与服务器的TCP连接。如果请求需要建立一个全新的连接,这个拦截器会处理连接的创建。 - CallServerInterceptor:
这个拦截器是处理实际请求和接收响应的。它将请求发送到服务器,并接收服务器的响应。这是请求生命周期中的最后一个拦截器。 - BridgeInterceptor:
桥接拦截器位于连接拦截器和调用服务器拦截器之间。它的主要作用是处理一些特殊情况,比如在HTTPS请求中,将原始的HTTP请求转换为HTTPS请求。此外,它还负责在请求中添加一些必要的头信息,如“User-Agent”。
3.自定义拦截器
-
需要实现
InterCeptor
接口public class MyInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {Request originalRequest = chain.request();// 创建一个新的 Request,可以在这里修改请求信息,例如添加请求头Request newRequest = originalRequest.newBuilder().header("Hello", "A-App").build();Response response = chain.proceed(newRequest);return response;} }
-
使用时,在OkHttpClient 中配置这个拦截器。想要添加多个拦截器的话,可以将其添加到拦截器链中。
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new MyInterceptor()).addInterceptor(new AnotherInterceptor()).build();
连接池
1.简介
-
OkHttp 连接池是 OkHttp 客户端的一部分,它负责管理 HTTP 连接的生命周期,以提高网络请求的效率。
-
连接池可以重用现有的连接,避免了频繁地创建和销毁连接,从而减少了延迟并节省了资源。
-
OkHttp 默认使用一个简单的连接池,可以通过配置 OkHttpClient 来调整连接池的行为。
2.常用参数配置选项
- maxIdleConnections(最大连接数):这是连接池中保持空闲的最大连接数。如果连接超过了这个限制,旧连接会被丢弃。
- connectTimeout(连接超时时间):这是建立连接的超时时间,单位是毫秒。
- readTimeout(读取超时时间):这是读取数据的超时时间,单位是毫秒。
- writeTimeout(写入超时时间):这是写入数据的超时时间,单位是毫秒。
- cleanupThreadInterval(清理间隔):这是连接池清理线程运行的时间间隔,默认为 5 分钟。
Dispatcher和线程池
1.简介
- Dispatcher中文是分发器的意思,和拦截器不同的是分发器不做事件处理,只做事件流向。
- 他负责将每一次Requst进行分发,压栈到自己的线程池,并通过调用者自己不同的方式进行异步和同步处理。
- 确保请求被顺序执行,并且控制着同时执行的请求数量,以避免网络拥塞和资源耗尽。
- Dispatcher与一个线程池一起工作,这个线程池由固定数量的线程组成。线程池的大小可以通过OkHttpClient的构造函数进行配置。
2.重要方法
-
RealCall.execute
execute方法同步地发送请求并等待响应, 当调用execute时,当前线程会阻塞,直到收到服务器的响应。
这个方法适用于简单的请求,或者当你需要直接处理响应(例如,作为同步操作)时。将RealCall加入Dispatcher的runningSyncCalls队列。
-
RealCall.enqueue
enqueue方法异步地发送请求,并将响应的回调放入事件队列中,当调用enqueue时,请求会被发送,但当前线程不会阻塞,可以继续执行其他任务。
响应的回调会在事件队列中等待处理,通常会在主线程上执行,确保用户界面可以流畅地响应用户交互。如果当前正在执行的RealCall的数量小于最大并发数,并且该call对应的Host上的call小于同一host上的最大并发数,则将该call加入runningAsyncCalls,并将这个call放到线程池中进行执行,否则加入readyAsyncCall排队等待。
3.DispatCher中的双端队列
-
readyAsyncCalls:准备运行的异步请求
异步的缓存,正在准备被消费的(用数组实现,可自动扩容,无大小限制)。
-
runningAsyncCalls:正在运行的异步请求
正在运行的 异步的任务集合,仅仅是用来引用正在运行的任务以判断并发量,注意它并不是消费者缓存。
-
runningSyncCalls:正在运行的同步请求
正在运行的,同步的任务集合。仅仅是用来引用正在运行的同步任务以判断并发量。
OkHttp 设置了默认的最大并发请求量 maxRequests = 64 和单个 Host 主机支持的最大并发量 maxRequestsPerHost = 5
4.总结
- Dispatcher和线程池在OkHttp中协同工作,确保网络请求被有效、高效地处理。
- Dispatcher负责请求的调度和管理,而线程池负责实际的网络操作和数据传输。
- 这种设计既保证了网络请求的有序执行,又避免了资源的过度消耗。
相关文章:

OkHttp
文章目录 OkHttp概要1.简介2.特点3.基本组成5.工作流程 拦截器1.简介2.内置拦截器3.自定义拦截器 连接池1.简介2.常用参数配置选项 Dispatcher和线程池1.简介2.重要方法3.DispatCher中的双端队列4.总结 OkHttp 概要 1.简介 OkHttp是一个开源的HTTP客户端,用于在J…...

uni-app 上传图片无反应 chooseImage失效
1、点击反应都没有 2、输出fail 信息 {"errMsg": "chooseImage:fail api scope is not declared in the privacy agreement", "errno": 112} 提示: 这个是小程序需要更新用户隐私策略 在小程序 微信公众平台 : 设置-&…...
学习Java十一天总结
目录 一、走进Java编程世界 二、变量、常量和运算符 三、if选择结构 四、switch选择结构 五、while循环结构 六、for循环结构 七、数组 八、深度循环结构 九、类和对象 十、类的无参方法 十一、类的带参方法 十二、字符串 一、走进Java编程世界 程序是为了让计算机…...

【光伏监控系统的相关产品有哪些】Acrel-1000DP分布式光伏监控系统
光伏发电系统是指无需通过热过程直接将光能转变为电能的发电系统。通常由光伏方阵、蓄电池组(蓄电池控制器)、逆变器、交流配电柜和太阳跟踪控制系统等设备组成。其特点是可靠性高、使用寿命长、不污染环境、能独立发电又能并网运行。 分布式光伏监控系…...

[Linux]互斥锁(什么是锁,为什么需要锁,怎么使用锁(接口),演示代码)
目录 一、锁的概念 一些需要了解的概念 什么是锁?为什么需要锁?什么时候使用锁?怎么定义锁? 二、锁的接口 1.初始化锁 2.加锁 3.申请锁 4.解锁 5.销毁锁 三、实践(写代码):黄牛抢票 M…...

Web基础06-AJAX,Axios,JSON数据
目录 一、AJAX 1.概述 2.主要作用 3.快速入门 4.AJAX的优缺点 (1)优点 (2)缺点 5.同源策略 二、Axios 1.概述 2.快速入门 3.请求方式别名 三、JSON 1.概述 2.主要作用 3.基础语法 4.JSON数据转换 (1…...
Java 文件序列化和反序列化
list序列化 /*** 序列化* param list* param filename* throws IOException*/public static void serializeList(List<Map<String, Object>> list, String filename) throws IOException {try (ObjectOutputStream oos new ObjectOutputStream(new FileOutputStre…...
NETLINK_ROUTE 与 NETLINK_SOCK_DIAG 的区别与用法
在 Linux 中,Netlink 是一种用于内核与用户空间之间通信的机制,通过不同的 Netlink 协议族(family)可以实现不同类型的通信。其中,NETLINK_ROUTE 和 NETLINK_SOCK_DIAG 是两种常用的 Netlink 协议族,它们具…...
docker yocto vscode
scode的docker插件怎么使用 vscode是一个基于VS Code的开发环境,它提供了一个Docker插件,可以帮助你在VS Code中使用Docker进行开发。下面是使用scode的Docker插件的步骤: 安装scode插件:在VS Code的扩展商店中搜索并安装scode插…...

使用ansible剧本进行lvm分盘
使用 Ansible 剧本(Playbook)进行 LVM 分区管理是一种自动化的方式,可以帮助管理员在多台主机上批量管理逻辑卷。 部署环境 3台主机,添加硬盘 ansible-galaxy collection install community.general 联网执行,下…...

【排序】快速排序
原理 对于一个数组x,快速排序流程如下: 确定分界点a,可以取x[l]、x[r]、x[l r / 2]、随机(四种都可以)调整区间,使得:区间被分成 < a 和 > a的两部分,左边 < aÿ…...

Python大数据实践:selenium爬取京东评论数据
准备工作 selenium安装 Selenium是广泛使用的模拟浏览器运行的库,用于Web应用程序测试。 Selenium测试直接运行在浏览器中,就像真正的用户在操作一样,并且支持大多数现代 Web 浏览器。 #终端pip安装 pip install selenium #清华镜像安装 p…...

信息系统项目管理师019:存储和数据库(2信息技术发展—2.1信息技术及其发展—2.1.3存储和数据库)
文章目录 2.1.3 存储和数据库1.存储技术2.数据结构模型3.常用数据库类型4.数据仓库 记忆要点总结 2.1.3 存储和数据库 1.存储技术 存储分类根据服务器类型分为:封闭系统的存储和开放系统的存储。封闭系统主要指大型机等服务器。开放系统指基于包括麒麟、欧拉、UNIX…...

Python基础(六)之数值类型元组
Python基础(六)之数值类型元组 1、简介 元组: 在Python中是内置的数据结构之一,是一个不可变的序列,切可以是任何类型数据。元组的元素放在()小括号内。一般我们希望数据不改变的时候使用 不可变与可变的…...

Chrome历史版本下载地址:Google Chrome Older Versions Download (Windows, Linux Mac)
最近升级到最新版本Chrome后发现页面居然显示错乱,是在无语, 打算退回原来的版本, 又发现官方只提供最新的版本下载, 为了解决这个问题所有收集了Chrome历史版本的下载地址分享给大家. Google Chrome Windows version 32-bit VersionSizeDate104.0.5112.10279.68 MB2022-05-30…...
ROS2纯跟踪实现(C++)
#include <tf2_ros/buffer.h> #include <tf2_ros/transform_broadcaster.h> #include <tf2_ros/transform_listener.h>#include <geometry_msgs/msg/transform_stamped.hpp> #include...

uniapp微信小程序随机生成canvas-id报错?
uniapp微信小程序随机生成canvas-id报错? 文章目录 uniapp微信小程序随机生成canvas-id报错?效果图遇到问题解决 场景: 子组件,在 mounted 绘制 canvas;App、H5端正常显示,微信小程序报错; 效…...

爬虫 Day2
resp.close()#关掉resp 一requests入门 (一) 用到的网页:豆瓣电影分类排行榜 - 喜剧片 import requestsurl "https://movie.douban.com/j/chart/top_list" #参数太长,重新封装参数 param {"type": "…...

达梦数据库SQL
达梦JSON函数技术文档 SQL中关键词处理 -- 必须要使用双引号包裹 select id,"comment" from t_cmp_rd_process;select id,"commit" from t_cmp_rd_gjj_eva;JSON_EXTRACT函数 -- party_sup_other_json 是包含JSON数据的列名。 -- $.content_abstract 是J…...
python教程——把视频转成gif
一、前言 很多网站提供视频转GIF的功能,但要么收费要么有广告,实际上可以通过python,几行代码就能够实现视频转gif。 二、使用方法 1安装必备库moviepy pip install moviepy -i https://pypi.tuna.tsinghua.edu.cn/simple 2. 写入代码 …...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...