【网络编程】okhttp深入理解

在这里插入图片描述
newCall 实际上是创建了一个 RealCall 有三个参数:OkHttpClient(通用配置,超时时间等) Request(Http请求所用到的条件,url等) 布尔变量forWebSocket(webSocket是一种应用层的交互方式,可双向交互,一般用不到,除非需要频繁刷新数据,股票等。)

	private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {this.client = client;this.originalRequest = originalRequest;this.forWebSocket = forWebSocket;}

Request会被进行多次封装(所以构造函数里对象被命名为originRequest)

在进行newCall().enqueue(),实际就是RealCallenqueue()

	@Override public void enqueue(Callback responseCallback) {synchronized (this) {if (executed) throw new IllegalStateException("Already Executed");executed = true;}//1transmitter.callStart();//2 关键client.dispatcher().enqueue(new AsyncCall(responseCallback));}

分别看1和2,主要看2

	public void callStart() {//跟踪程序错误this.callStackTrace = Platform.get().getStackTraceForCloseable("response.body().close()");//eventListener是一个监听器,连接的接入和关闭,对程序进行监听eventListener.callStart(call);}

client.dispatcher()返回一个Dispatcher类对象,即线程调度器,然后用这个去进行异步操作,代入参数为一个AsyncCall

	void enqueue(AsyncCall call) {synchronized (this) {//1readyAsyncCalls.add(call);// Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to// the same host.//2if (!call.get().forWebSocket) {AsyncCall existingCall = findExistingCallWithHost(call.host());if (existingCall != null) call.reuseCallsPerHostFrom(existingCall);}}//3promoteAndExecute();}
  • 1的readyAsyncCalls 是一个 ArrayDeque<AsyncCall> ,存放 准备要执行但还没有执行,然后会在3的promoteAndExecute()中执行
	private boolean promoteAndExecute() {assert (!Thread.holdsLock(this));List<AsyncCall> executableCalls = new ArrayList<>();boolean isRunning;synchronized (this) {for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {AsyncCall asyncCall = i.next();if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.i.remove();asyncCall.callsPerHost().incrementAndGet();executableCalls.add(asyncCall);runningAsyncCalls.add(asyncCall);}isRunning = runningCallsCount() > 0;}for (int i = 0, size = executableCalls.size(); i < size; i++) {AsyncCall asyncCall = executableCalls.get(i);asyncCall.executeOn(executorService());}return isRunning;}

promoteAndExecute会挑选那些不会导致超负载的call(不超过AsyncCall对应的maxRequest),放进executableCallsrunningAsyncCalls,然后去执行,就是去遍历executableCalls然后执行。
分别执行就是把调用每一个asyncCall 的 executeOn():

	void executeOn(ExecutorService executorService) {assert (!Thread.holdsLock(client.dispatcher()));boolean success = false;try {executorService.execute(this);success = true;} catch (RejectedExecutionException e) {InterruptedIOException ioException = new InterruptedIOException("executor rejected");ioException.initCause(e);transmitter.noMoreExchanges(ioException);responseCallback.onFailure(RealCall.this, ioException);} finally {if (!success) {client.dispatcher().finished(this); // This call is no longer running!}}}

核心只有一行:

executorService.execute(this);

这里就已经切换线程了,执行的都是传入的 executorService.对象 的execute()方法,都会在后台执行

	@Override protected void execute() {boolean signalledCallback = false;  // 标记回调是否已触发transmitter.timeoutEnter();  // 进入超时处理逻辑try {Response response = getResponseWithInterceptorChain();  // 调用拦截器链获取responsesignalledCallback = true;  // 标记回调已触发responseCallback.onResponse(RealCall.this, response);  // 调用response的回调函数} catch (IOException e) {if (signalledCallback) {// 不要重复触发回调!Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);} else {responseCallback.onFailure(RealCall.this, e);}} catch (Throwable t) {cancel();  // 取消请求if (!signalledCallback) {IOException canceledException = new IOException("canceled due to " + t);canceledException.addSuppressed(t);responseCallback.onFailure(RealCall.this, canceledException);  // 调用失败回调函数}throw t;} finally {client.dispatcher().finished(this);  // 请求结束,将请求移出调度队列}}

其中回调函数就是当初我们在应用层所定义的Callback里边定义的onFailure()onResponse(),然后如果出现异常,会进行调用相应的方法。

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

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

相关文章

2.22使用GPIO子系统编写LED灯驱动,应用程序测试//注册三个按键的中断

使用GPIO子系统编写LED灯驱动 驱动程序 #include <linux/init.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/gpio.h> #include <linux/timer.h> #include <linux/interrupt.h>…

ubuntu22.04@Jetson Orin Nano之CSI IMX219安装

ubuntu22.04Jetson Orin Nano之CSI IMX219安装 1. 源由2. 安装2.1 硬件安装2.2 软件配置2.3 新增摄像头 3. 效果4. 参考资料 1. 源由 折腾半天时间&#xff0c;捣鼓这个套装摄像头(IMX219)的安装&#xff0c;死活就是没有这个设备。世界总是这么小&#xff0c;看看遇到问题的大…

排序算法之——快速排序

快速排序 1.基本思想2.图示详解——以升序排列为例3.对基本思想和图示的补充说明4.代码实现5.空间、时间复杂度5.1最好情况5.2最坏情况 6.区间按照基准值划分的方法6.1 Hoare法6.2 挖坑法 7.优化措施7.1三数取中法7.1.1三数取中法——核心代码7.1.2优化效果7.1.3补充说明 7.2 递…

docker 容器内服务随容器自动启动

docker 容器内服务随容器自动启动 背景准备工作方案一&#xff0c;直接修改.bashrc文件&#xff08;简单粗暴&#xff09;方案二&#xff0c;编写启动脚本加入.bashrc文件&#xff08;文明一点&#xff09;制作nginx服务自启动镜像测试新镜像&#xff0c;nginx服务随容器自动启…

回显服务器的制作方法

文章目录 客户端和服务器TCP和UDP的特点UDP socket api的使用DatagramSocketDatagramPacketInetSocketAddress API 做一个简单的回显服务器UDP版本的回显服务器TCP版本的回显服务器 客户端和服务器 在网络中&#xff0c;主动发起通信的一方是客户端&#xff0c;被动接受的这一方…

Rman全备和增量备份说明

RMAN备份分为全备和增量备份&#xff0c;全备不能成为增量备份策略的一部分&#xff0c;它也不能作为后续增量备份的基础。 RMAN增量备份分为0、1、2三级&#xff0c;其中0级备份是增量备份的基础&#xff0c;备份内容也跟全备份一样&#xff0c;要使用增量备份&#xff0c;必…

华为交换机如何配置Web网管登录?直接用网页管理交换机

Web网管是一种对交换机的管理方式&#xff0c;它利用交换机内置的Web服务器&#xff0c;为用户提供图形化的操作界面。用户可以从终端通过HTTPS登录到Web网管&#xff0c;对交换机进行管理和维护&#xff0c;同时也非常方便。 一、配置思路&#xff1a; 1、配置管理IP地址&am…

mysql 自定义函数create function

方便后续查询&#xff0c;做以下记录&#xff1b; 自定义函数是一种与存储过程十分相似的过程式数据库对象&#xff0c; 它与存储过程一样&#xff0c;都是由 SQL 语句和过程式语句组成的代码片段&#xff0c;并且可以被应用程序和其他 SQL 语句调用。 自定义函数与存储过程之间…

提供英语励志名言的软件有哪些?这些软件不可错过

提供英语励志名言的软件有哪些&#xff1f;在追求个人成长和激励的道路上&#xff0c;英语励志名言常常为我们提供前进的动力。这些言简意赅、充满智慧的话语&#xff0c;不仅能在我们迷茫时指引方向&#xff0c;还能在挫折中给予我们勇气和力量。如今&#xff0c;随着科技的发…

stm32和嵌入式linux可以同步学习吗?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「stm3的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;如果需要使用STM32&#xff0c;建…

http://127.0.0.1:9222/json打不开Chrome环境变量问题

解决方案&#xff1a; 系统环境变量Path设置错误&#xff0c; 1、先看下端口是否占用&#xff1a;netstat -ano|findstr “9222” &#xff0c; 如下127.0.0.1:9222端口显示LISTENING是正常的 如果是SYN_SENT可能不太正常&#xff0c;这个时候&#xff0c; taskkill /PID 端…

【前端素材】推荐优质后台管理系统APP Zina平台模板(附源码)

一、需求分析 当我们从多个层次来详细分析后台管理系统时&#xff0c;可以将其功能和定义进一步细分&#xff0c;以便更好地理解其在不同方面的作用和实际运作。 1. 功能层次 a. 用户管理功能&#xff1a; 用户注册和登录&#xff1a;管理用户账户的注册和登录过程。权限管…

如何使用Docker部署开源Leanote蚂蚁笔记并发布个人博客至公网

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 文章目录 1. 安装Docker2. Docker本地部署Leanote蚂蚁笔记3. 安装…

notepad++运行python闪一下就没啦

问题&#xff1a;Notepad直接快捷键运行Python代码,出现闪一下就没了 解决措施&#xff1a; ①点击菜单运行(Run) --> 运行(Run)弹出的对话框 ②把 cmd /k python "$(FULL_CURRENT_PATH)" & ECHO. & PAUSE & EXIT 粘贴进入这个对话框内 ③点击保存&a…

由面试题“Redis是否为单线程”引发的思考

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

边坡位移监测设备:守护工程安全的前沿科技

随着现代工程建设的飞速发展&#xff0c;边坡位移监测作为预防山体滑坡、泥石流等自然灾害的重要手段&#xff0c;日益受到人们的关注。边坡位移监测设备作为这一领域的关键技术&#xff0c;以其高精度、实时监测的特点&#xff0c;成为守护工程安全的重要武器。 一、边坡位移…

信钰证券|印花税下降对股市的影响?印花税下降利好哪些板块?

投资者在买卖股票时&#xff0c;需求交纳一定的佣金费用、印花税和过户费用&#xff0c;其间印花税和过户费用&#xff0c;随着方针的变动&#xff0c;会进行相应的调整&#xff0c;那么&#xff0c;印花税下降对股市的影响&#xff1f;印花税下降利好哪些板块&#xff1f; 印花…

(科目三)信息技术基础

1.信息与信息技术概述 1.1 信息的定义和表示 一、信息的定义&#xff1a; 信息就是通过语言、文字、图形/图像、声音、视频等传播的内容。 信息≠消息&#xff0c;信息就是消息的内核&#xff0c;消息是信息的外壳。 信息不是某种信号&#xff0c;也不等同于知识。 数据&…

算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习三(leetcode真题剖析)

算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习三 01.字母大小写全排列02.优美的排列03.N 皇后04.有效的数独 01.字母大小写全排列 题目链接&#xff1a;https://leetcode.cn/problems/letter-case-permutation/ 给定一个字符串 s &#xff0c;通过将字符串 s 中的每个字…

安装Windows Server 2025 搭建免费云桌面系统

介绍 Windows Server 2025 为 Hyper-V 带来了多项增强功能和新的存储特性&#xff0c;主要用于优化虚拟机的运行体验。这些新特性涵盖 GPU 虚拟化、新的 ReFS 去重功能&#xff0c;以及在非 AD 域的集群上进行虚拟机实时迁移。 云桌面方案的用户最关心的GPU-P的技术也将在Win…