Android OkHttp 源码浅析一
演进之路:原生Android框架不好用 ---- HttpUrlConnect 和 Apache HTTPClient
第一版 底层使用HTTPURLConnect
第二版 Square构建 从Android4.4开始
基本使用:
val okhttp = OkHttpClient()val request = Request.Builder().url("http://www.baidu.com").build()okhttp.newCall(request).enqueue(object : okhttp3.Callback{override fun onFailure(call: okhttp3.Call, e: IOException) {Log.e("--->",e.message!!)}override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {Log.e("--->",response.body!!.string())}})//enqueue Call接口定义的抽象方法
//newCall RealCall创建出 有三个参数 1 okhttpclient 2.quest originnalRequest 3. forWebSocket //Booleaan
//WebSocket 是通过http创建连接
//
override fun enqueue(responseCallback: Callback) {check(executed.compareAndSet(false, true)) { "Already Executed" }callStart()
//dispatcher 用来做线程调度 管理 Executor 线程池
//MaxRequests = 64 最大64个线程
//MaxRequestPerHost = 5 最多同一主机线程 5client.dispatcher.enqueue(AsyncCall(responseCallback))}override fun isExecuted(): Boolean = executed.get()private fun callStart() {
//跟踪错误分析和记录this.callStackTrace = Platform.get().getStackTraceForCloseable("response.body().close()")
//监听一系列事件 连接建立 断开连接 报文 head body 发送等eventListener.callStart(this)}
@get:Synchronized var maxRequests = 64 最多连接数量 64
@get:Synchronized var maxRequestsPerHost = 5 同一主机 5
internal fun enqueue(call: AsyncCall) {synchronized(this) {readyAsyncCalls.add(call)// Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to// the same host.if (!call.call.forWebSocket) {val existingCall = findExistingCallWithHost(call.host)if (existingCall != null) call.reuseCallsPerHostFrom(existingCall)}}promoteAndExecute()}
同步方法,Deque 双向队列
AsyncCall 共享变量 记录连接数等
if (!call.call.forWebSocket) {//记录数量val existingCall = findExistingCallWithHost(call.host)if (existingCall != null) call.reuseCallsPerHostFrom(existingCall) }
private fun promoteAndExecute(): Boolean {this.assertThreadDoesntHoldLock()val executableCalls = mutableListOf<AsyncCall>()val isRunning: Booleansynchronized(this) {val i = readyAsyncCalls.iterator()while (i.hasNext()) {val asyncCall = i.next()if (runningAsyncCalls.size >= this.maxRequests) break // Max capacity.if (asyncCall.callsPerHost.get() >= this.maxRequestsPerHost) continue // Host max capacity.i.remove()asyncCall.callsPerHost.incrementAndGet()executableCalls.add(asyncCall)runningAsyncCalls.add(asyncCall)}isRunning = runningCallsCount() > 0}for (i in 0 until executableCalls.size) {val asyncCall = executableCalls[i]asyncCall.executeOn(executorService)}return isRunning}
promoteAndExecute 准备执行函数
readyAsyncCalls 没有执行过的请求 不会超出限制 64 or 5
executableCalls 添加到calls 然后取出遍历 执行 executeOn
val i = readyAsyncCalls.iterator() 遍历被执行的call
if (runningAsyncCalls.size >= this.maxRequests) break // Max capacity. if (asyncCall.callsPerHost.get() >= this.maxRequestsPerHost) continue // Host max capacity. 超出连接限制的数量 终止请求
i.remove() //移除当前请求 asyncCall.callsPerHost.incrementAndGet() executableCalls.add(asyncCall) runningAsyncCalls.add(asyncCall)
runningAsyncCalls 正在执行的Call
for (i in 0 until executableCalls.size) {
val asyncCall = executableCalls[i]
遍历准备执行的call 然后调用executeOn
asyncCall.executeOn(executorService)
}
Okhttp enqueue ----> newCall ---> RealCall enqueue ------> 执行 dispatcher . enqueue ----> 添加到readyAsyncCalls ----> promoteAndExecute ---executeOn 执行
fun executeOn(executorService: ExecutorService) {client.dispatcher.assertThreadDoesntHoldLock()var success = falsetry {executorService.execute(this)success = true} catch (e: RejectedExecutionException) {val ioException = InterruptedIOException("executor rejected")ioException.initCause(e)noMoreExchanges(ioException)responseCallback.onFailure(this@RealCall, ioException)} finally {if (!success) {client.dispatcher.finished(this) // This call is no longer running!}}}
executorService dispatcher 内部类管理的对象 线程调度 参数是runnable
executorService.execute(this) 线程切换到后台线程 Async 实现了Runnable
线程调度
override fun run() {threadName("OkHttp ${redactedUrl()}") {var signalledCallback = falsetimeout.enter()try {val response = getResponseWithInterceptorChain()signalledCallback = trueresponseCallback.onResponse(this@RealCall, response)} catch (e: IOException) {if (signalledCallback) {// Do not signal the callback twice!Platform.get().log("Callback failure for ${toLoggableString()}", Platform.INFO, e)} else {responseCallback.onFailure(this@RealCall, e)}} catch (t: Throwable) {cancel()if (!signalledCallback) {val canceledException = IOException("canceled due to $t")canceledException.addSuppressed(t)responseCallback.onFailure(this@RealCall, canceledException)}throw t} finally {client.dispatcher.finished(this)}}}
val response = getResponseWithInterceptorChain() 获取相应
getResponseWithInterceptorChain 请求数据的方法封装
responseCallback 代码里声明传入的Callback
相关文章:
Android OkHttp 源码浅析一
演进之路:原生Android框架不好用 ---- HttpUrlConnect 和 Apache HTTPClient 第一版 底层使用HTTPURLConnect 第二版 Square构建 从Android4.4开始 基本使用: val okhttp OkHttpClient()val request Request.Builder().url("http://www.baidu.com").buil…...
【Redis】——Redis基础的数据结构以及应用场景
什么是redis数据库 Redis 是一种基于内存的数据库,对数据的读写操作都是在内存中完成,因此读写速度非常快,常用于缓存,消息队列、分布式锁等场景。,Redis 还支持 事务 、持久化、Lua 脚本、多种集群方案(主…...
SpringBoot+WebSocket搭建多人在线聊天环境
一、WebSocket是什么? WebSocket是在单个TCP连接上进行全双工通信的协议,可以在服务器和客户端之间建立双向通信通道。 WebSocket 首先与服务器建立常规 HTTP 连接,然后通过发送Upgrade标头将其升级为双向 WebSocket 连接。 WebSocket使得…...
推荐适用于不同规模企业的会计软件:选择最适合您企业的解决方案
高效的会计软件不仅可以协助企业进行财务管理,做出科学的财务决策,还可以对企业数字化转型提供助力。不同规模的企业需要根据其特定需求选择适合的会计软件。那么有什么适合不同规模企业的会计软件推荐吗? 小型企业的选择 对于小型企业而言&…...
Apache Zookeeper架构和选举机制
ZooKeeper是一个开源的分布式协调服务,旨在解决分布式系统中的一致性、配置管理、领导者选举等问题。它由Apache软件基金会维护,是Hadoop生态系统的一部分,被广泛用于构建高可用、可靠和具有一致性的分布式应用程序和服务。 ZooKeeper提供了一个层次化的命名空间,类似于文…...
车联网TCU USB的配置和使用
1 usb_composition命令 # cat /sbin/usb/target # cd /sys/class/android_usb/android0 # cat functions console shows that QCOM’s default configuration Usage: usb_composition [Pid] [HSIC] [PERSISTENT] [IMMEDIATE] [FROM_ADBD] usb_composition 9025 n y y Then this…...
Linux系统USB摄像头测试程序(三)_视频预览
这是在linux上usb摄像头视频预览程序,此程序用到了ffmpeg、sdl2、gtk3组件,程序编译之前应先安装他们。 #include <sys/ioctl.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <zconf.h> …...
目标检测任务数据集的数据增强中,图像水平翻转和xml标注文件坐标调整
需求: 数据集的数据增强中,有时需要用到图像水平翻转的操作,图像水平翻转后,对应的xml标注文件也需要做坐标的调整。 解决方法: 使用pythonopencvimport xml.etree.ElementTree对图像水平翻转和xml标注…...
系统架构的演变
随着互联网的发展,网站应用的规模不断扩大,常规的应用架构已无法应对,分布式服务架构以及微服务架构势在必行,必需一个治理系统确保架构有条不紊的演进。 单体应用架构 Web应用程序发展的早期,大部分web工程(包含前端…...
IDC发布《亚太决策支持型分析数据平台评估》报告,亚马逊云科技位列“领导者”类别
日前,领先的IT市场研究和咨询公司IDC发布《2023年亚太地区(不含日本)决策支持型分析数据平台供应商评估》1报告,亚马逊云科技位列“领导者”类别。IDC认为,亚马逊云科技在解决方案的协同性、敏捷性、完整性、及时性、经…...
C#之OpenFileDialog创建和管理文件选择对话框
OpenFileDialog 是用于图形用户界面(GUI)编程的一个类,它用于显示一个对话框,允许用户选择要打开的文件。在需要用户加载或打开文件的应用程序中(如文本编辑器、图像查看器或文档处理器),这是一…...
Java中使用MongoTemplate 简单操作MongoDB
Autowired private MongoTemplate mongoTemplate; User:封装的对象 插入:mongoTemplate.insert(user); 根据id查询:mongoTemplate.findById(id, User.class); 查询所有:mongoTemplate.findAll(User.class); 条件查询&#…...
[Mac软件]Pixelmator Pro 3.3.12 专业图像编辑中文版
Pixelmator Pro是专为Mac设计的功能强大,美观且易于使用的图像编辑器。借助广泛的专业级无损图像编辑工具,Pixelmator Pro可使您发挥出最佳的照片效果,创建华丽的构图和设计,绘制,绘画,应用令人惊叹的效果&…...
吴恩达 GPT Prompting 课程
Prompting Guidelines 目录 Guidelines for PromptingPrompting Principles Principle 1: Write clear and specific instructions1.1: Use delimiters to clearly indicate distinct parts of the input1.2: Ask for a structured output1.3: Ask the model to check whether …...
gpt3.5写MATLAB代码剪辑视频,使之保留画面ROI区域
% 输入和输出文件名 inputVideoFile input_video.mp4; outputVideoFile output_video.mp4;% 创建 VideoReader 和 VideoWriter 对象 videoReader VideoReader(inputVideoFile); outputVideo VideoWriter(outputVideoFile, MPEG-4); outputVideo.FrameRate videoReader.Fra…...
设计模式二十一:状态模式(State Pattern)
一个对象的内部状态发生变化时,允许对象改变其行为。这种模式使得一个对象看起来好像在运行时改变了它的类,主要目的是将状态的行为从主要对象中分离出来,使得主要对象不必包含所有状态的逻辑,而是将每个状态的行为封装在独立的类…...
【校招VIP】产品思维能力之产品设计
考点介绍: 对于产品经理来说最重要的就是产品思维,而拥有一个好的产品思维需要做到以下三点: 1、把握关键点的能力 2、出方案,协调资源,说服团队把资源倾斜到关键点上的能力 3、评估关键点进展程度的能力 『产品思维能…...
微信小程序卡片横向滚动竖图
滚动并不是使用swiper,该方式使用的是scroll-view实现 Swiper局限性太多了,对竖图并不合适 从左往右滚动图片示例 wxml代码: <view class"img-x" style"margin-top: 10px;"><view style"margin: 20rpx;…...
SpringBoot项目(支付宝整合)——springboot整合支付宝沙箱支付 从极简实现到IOC改进
目录 引出git代码仓库准备工作支付宝沙箱api内网穿透 [natapp.cn](https://natapp.cn/#download) springboot整合—极简实现版1.导包配置文件2.controller层代码3.进行支付流程4.支付成功回调 依赖注入的改进1.整体结构2.pom.xml文件依赖3.配置文件4.配置类,依赖注入…...
【AIGC】一款离线版的AI智能换脸工具V2.0分享(支持图片、视频、直播)
随着人工智能技术的爆发,AI不再局限于大语言模型,在图片处理方面也有非常大的进步,其中AI换脸也是大家一直比较感兴趣的,但这个技术的应用一直有很大的争议。 今天给大家分享一个开源你的AI换脸工具2.0,只需要一张所需…...
管理类联考——逻辑——真题篇——按知识分类——汇总篇——一、形式逻辑——选言——相容选言——或
文章目录 第五章 选言命题:相容选言-或;不相容选言-要么要么第一节 选言-相容选言-或-推结论-A或B为真,则非A→B,非B→A(否一则肯一)真题(2010-28)-选言-相容选言-或-推结论-(1)A或B为真,A为假:得B为真(否一则肯一);真题(2012-29)-选言-相容选言-或-推结论-(1)…...
Git如何操作本地分支仓库?
基本使用TortoiseGit 操作本地仓库(分支) 分支的概念 几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,避免影响开发主线。多线程开发,可以同时开启多个任务的开发,多个任务之间互不影响。 为何要…...
WPS右键新建没有docx pptx xlsx 修复
解决wps右键没有新建文档的问题 右键没有新建PPT和Excel 1 wps自带的修复直接修复没有用 以上不管咋修复都没用 2 先编辑注册表 找到 HKEY_CLASSES_ROOT CTRLF搜文件扩展名 pptx docx xlsx 新建字符串 三种扩展名都一样操作 注册表编辑之后再次使用wps修复 注册组件&am…...
【巧学C++之西游篇】No.2 --- C++闹天宫,带着“重载“和“引用“
文章目录 前言🌟一、函数重载🌏1.1.函数重载概念🌏1.2.C支持函数重载的原理 -- 名字修饰 🌟二、引用🌏2.1.引用的概念🌏2.2.引用特性🌏2.3.常引用🌏2.4.使用场景🌏2.5.传…...
【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)
【关键字】 音频编码、管道模式、createEncoder 【写在前面】 在使用API6开发HarmonyOS应用时,如何将pcm源文件进行编码并写入文件,最后生成aac文件,本文直接附上主要代码开发步骤供大家参考。 【主要功能代码】 import ohos.media.codec.…...
KaiwuDB CTO 魏可伟:回归用户本位,打造“小而全”的数据库
8月16日,KaiwuDB 受邀亮相第十四届中国数据库技术大会 DTCC 2023。KaiwuDB CTO 魏可伟接受大会主办方的采访,双方共同围绕“数据库架构演进、内核引擎设计以及不同技术路线”展开深度探讨。 以下是采访的部分实录 ↓↓↓ 40 多年前,企业的数…...
行业追踪,2023-08-22
自动复盘 2023-08-22 凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让…...
浏览器安装selenium驱动,以Microsoft Edge安装驱动为例
Selenium是一个用于Web应用程序测试的自动化工具。它可以直接在浏览器中运行,模拟真实用户对浏览器进行操作。利用selenium,可以驱动浏览器执行特定的动作,比如:点击、下拉等等,还可以获取浏览器当前呈现的页面的源代码…...
边缘计算网关是如何提高物联网的效率的?
随着物联网的持续发展,物联网应用的丰富和规模的扩大,带来了海量的数据处理、传输和计算需求。 传统的“数据中央处理”模式越来越难以适应物联网的扩展速度,在这一趋势下,边缘计算在物联网系统的部署运营中就发挥出了显著的增效…...
AWVS安装~Windows~激活
目录 1.下载安装包 2.双击acunetix_15.1.221109177.exe进行安装 3.配置C:\Windows\System32\drivers\etc\hosts 4.复制wvsc.exe到C:\Program Files (x86)\Acunetix\15.1.221109177下 5.复制license_info.json与wa_data.dat到C:\ProgramData\Acunetix\shared\license下&…...
网站设置万事达u卡/百度官网认证价格
2019-02-14 【小记】 RO段、RW段和ZI段 --Image$$??$$Limit 含义(zz)转载于:https://www.cnblogs.com/skullboyer/p/10373972.html...
做宣传图册在什么网站/网络营销活动策划方案模板
ylbtech-JS:函数-导航函数定义返回函数调用一个函数调用一个函数(带参数)返回值的函数调用外部的js文件JS:3.1,函数(function)-定义返回顶部 1,定义函数语法 通过定义函数名称,参数和代码语句来创建函数。function 函数…...
手机网站怎么建立/seo免费教程
这是一道选择题,答案是:(设,收银员和顾客的私有信号量为S1和S2) a:P(Sn) ;b1:V(S1);b2:P(S2);c1:P(S1);c2: V(S2); 我是…...
无锡网站建设推荐智勇/seo公司是做什么的
综合习题一、选择题1. 计算机网络是地理上分散的多台(C)遵循约定的通信协议,通过软硬件互联的系统。A. 计算机B. 主从计算机C. 自主计算机D. 数字设备2. 密码学的目的是(C)。A. 研究数据加密B. 研究数据解密C. 研究数据保密D. 研究信息安全3. 假设使用一种加密算法&…...
如何组织公司做网站/山东建站管理系统
var test{name:"name",age:"12"};test.id "12345"; 直接定义添加就成了...
建立网站教程视频/汕头网站建设方案推广
随着信息技术的发展,计算机在我们的日常生活中扮演了越来越重要的作用,通过现有的技术以及当今在计算机领域还在研究中的尖端科技分析,计算机的发展将趋向超高速、超小型、平行处理和智能化,量子、光子、分子和纳米计算机将具有感知、思考、判…...