【Android】OKHttp网络请求原理和弱网优化

【Android】OKHttp网络请求原理和弱网优化


1. OkHttp 网络请求原理

OkHttp 的请求过程可以分为 四个关键阶段
(假设你是通过 OkHttpClient.newCall(request).enqueue(callback) 发的请求)

OkHttpClient│▼
Dispatcher (调度器)│▼
RealCall (真正的Call实现)│▼
Interceptor Chain (拦截器责任链)│▼
Stream/Connection (TCP/SSL/HTTP2)

核心组件

  1. OkHttpClient
    • 全局配置(超时、拦截器、连接池、缓存等)
    • 线程安全,推荐单例。
  2. Dispatcher(调度器)
    • 维护同步/异步请求队列
    • 默认异步最大并发请求数 = 64(每个host默认5个并发)
  3. RealCall
    • 封装了一个具体的 HTTP 调用过程。
    • 同步时走 execute(),异步时走 enqueue()
  4. Interceptor Chain(拦截器链)
    OkHttp 的核心,按顺序执行:
    • Application Interceptor(应用拦截器)
      你自己加的,比如统一加 Header、埋点。
    • RetryAndFollowUpInterceptor(重试&重定向)
      处理失败重试、HTTP 3xx 跟随跳转。
    • BridgeInterceptor(桥接拦截器)
      把用户的 Request 转成可发的 HTTP Request(补默认 Header,比如 Content-Type)。
    • CacheInterceptor(缓存拦截器)
      负责读写缓存(符合 HTTP 缓存协议的才会生效)。
    • ConnectInterceptor(连接拦截器)
      找到可用的连接(可能复用连接池的 TCP/HTTP2)。
    • CallServerInterceptor(发送请求 & 读取响应)。
  5. 连接池(ConnectionPool)
    • 复用 TCP 连接(默认 5 分钟闲置后关闭)
    • 对弱网非常重要,减少 TCP/TLS 握手开销。

2. 弱网优化思路(基于 OkHttp 原理)

弱网优化要考虑 连接建立数据传输失败恢复 三方面:


(1) 减少连接开销

  • 启用连接池(默认已开启)

    new OkHttpClient.Builder().connectionPool(new ConnectionPool(10, 5, TimeUnit.MINUTES))
    

    提高空闲连接数和保活时间,减少频繁建连。

  • HTTP/2
    如果服务端支持,启用 HTTP/2 可以一个 TCP 连接多路复用多个请求,减少弱网下握手阻塞。

  • DNS 预解析 + 缓存
    弱网 DNS 解析可能很慢,可以提前解析:

    OkHttpClient client = new OkHttpClient.Builder().dns(hostname -> {List<InetAddress> addresses = Arrays.asList(InetAddress.getAllByName(hostname));return addresses; // 可做本地缓存}).build();
    

(2) 控制请求超时策略

弱网时默认超时可能不合适,可以分类型调整:

OkHttpClient client = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS)   // 建立连接超时.readTimeout(8, TimeUnit.SECONDS)      // 读取超时.writeTimeout(8, TimeUnit.SECONDS)     // 写入超时.retryOnConnectionFailure(true)        // 启用失败重试.build();
  • 短连接超时:弱网时快速放弃连接不上的 IP,走备用。
  • 读写时间略放宽:弱网传输慢,避免误判失败。

(3) 分片/断点续传

  • 大文件上传/下载弱网下易中断,建议用 Range 分片

    Range: bytes=0-1023
    
  • 中断后只请求剩余部分,减少重传。


(4) 降级策略

弱网下可以:

  • 压缩数据(Gzip / WebP 图片)
    OkHttp 默认支持 Gzip 解压,服务端加 Content-Encoding: gzip 即可。
  • 减少请求次数
    合并多个小请求为一个大请求。
  • 先本地缓存/后上传
    弱网先本地存储(Room/SQLite),网络恢复后批量上传。

(5) 智能重试

默认的 RetryAndFollowUpInterceptor 只会在特定错误下重试。
你可以自定义拦截器来做指数退避重试

class RetryInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {int tryCount = 0;IOException lastException;while (tryCount < 3) {try {return chain.proceed(chain.request());} catch (IOException e) {lastException = e;tryCount++;Thread.sleep((long) Math.pow(2, tryCount) * 500); // 500ms, 1s, 2s}}throw lastException;}
}

(6) 弱网检测 + 动态策略

可用 TrafficStats 或测速接口判断弱网,然后动态调整 OkHttp:

if (isWeakNetwork()) {// 降低并发、延长超时
} else {// 正常配置
}

总结

  • OkHttp 的本质是拦截器责任链 + 连接池复用,弱网优化重点是减少握手、缓存结果、控制超时、重试与降级
  • 最实用的三个点:连接复用(ConnectionPool)HTTP/2重试退避策略
  • 如果弱网还卡,可以加弱网检测配合动态参数调整。

还可以额外参考一下【淘宝移动端统一网络库的架构演进和弱网优化技术实践】

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

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

相关文章

概率论基础教程第4章 随机变量(四)

4.7 泊松随机变量 定义 泊松随机变量&#xff1a;如果一个取值于 $ 0, 1, 2, \ldots $ 的随机变量对某一个 $ \lambda > 0 $&#xff0c;其分布列为&#xff1a; p(i)P{Xi}e−λλii!i0,1,2,⋯(7.1) \boxed{p(i) P\{X i\} e^{-\lambda} \frac{\lambda^i}{i!} \qquad i 0…

Unity高级开发:反射原理深入解析与实践指南 C#

Unity高级开发&#xff1a;反射原理深入解析与实践指南 在Unity游戏开发中&#xff0c;反射&#xff08;Reflection&#xff09; 是一项强大的元编程技术&#xff0c;它允许程序在运行时动态地获取类型信息、创建对象和调用方法。根据Unity官方统计&#xff0c;超过78%的商业游…

任务五 推荐页面功能开发

一、推荐页面需求分析 由推荐页面效果图,可以看出,推荐页面主要由顶部轮播图和歌单列表页面组成 二、推荐页面轮播图组件封装 由于轮播图,可能在项目多个地方用到,因此可以将轮播图抽调成一个组件,然后各个页面调用这个组件。 在开发轮播图组件时,需要安装better-scro…

【工具使用-Docker容器】构建自己的镜像和容器

1. 镜像和容器介绍 镜像&#xff08;Image&#xff09;是一个只读的模板&#xff0c;包含了运行某个应用所需的全部内容&#xff0c;比如&#xff1a; 操作系统&#xff08;比如 Ubuntu&#xff09;应用程序代码运行环境&#xff08;如 Python、Java、Node.js 等&#xff09;库…

Apache Shiro550 漏洞(CVE-2016-4437):原理剖析与实战 SOP

在 Web 安全领域&#xff0c;反序列化漏洞一直是威胁等级极高的存在&#xff0c;而 Apache Shiro 框架中的 Shiro550 漏洞&#xff08;CVE-2016-4437&#xff09;&#xff0c;更是因利用门槛低、影响范围广&#xff0c;成为渗透测试中频繁遇到的经典漏洞。本文将从 “原理拆解”…

安卓开发者自学鸿蒙开发3持久化/数据与UI绑定

AppStorage,PersistentStorage与StorageLink AppStorage是应用全局状态管理器,数据存储于内存中,常见的如全局的黑暗模式,StorageLink是用来绑定AppStorage的键到ui上的工具,省去了用户手写代码的无聊过程,PersistentStorage可以绑定AppStorage的键,自动持久化到磁盘,同时支持多…

GitHub宕机生存指南:从应急协作到高可用架构设计

GitHub宕机生存指南&#xff1a;从应急协作到高可用架构设计 摘要&#xff1a; GitHub作为全球开发者的协作中心&#xff0c;其服务稳定性至关重要。然而&#xff0c;任何在线服务都无法保证100%的可用性。本文深入探讨了当GitHub意外宕机时&#xff0c;开发团队应如何应对。我…

机器学习算法篇(十三)------词向量转化的算法思想详解与基于词向量转换的文本数据处理的好评差评分类实战(NPL基础实战)

目录 一、词向量原理介绍 (1). 词向量的核心概念 (2). 传统文本表示的局限性 1. 独热编码&#xff08;One-Hot Encoding&#xff09; 2. 词袋模型&#xff08;Bag of Words&#xff09; 3. TF-IDF (3). 词向量的核心原理 (4). 主流词向量模型 1. Word2Vec&#xff08;20…

JS自定义函数(2)

1. 变量的作用域全局变量定义&#xff1a;在函数外声明的变量作用范围&#xff1a;在整个JS文档中生效生命周期&#xff1a;页面关闭时销毁局部变量定义&#xff1a;在函数内用 var 声明的变量作用范围&#xff1a;只能在函数内部使用生命周期&#xff1a;函数执行完毕时销毁作…

【数据集】Argoverse 数据集:自动驾驶研究的强大基石

Argoverse数据集&#xff1a;自动驾驶研究的强大基石 在自动驾驶技术蓬勃发展的当下&#xff0c;高质量的数据集对于推动相关算法研究和模型训练起着举足轻重的作用。Argoverse 数据集便是其中的佼佼者&#xff0c;它为自动驾驶领域的众多任务提供了丰富且优质的数据资源。 一、…

--- 哈希表和哈希冲突 ---

哈希&#xff08;散列&#xff09;方法是对插入的数据通过哈希函数计算出一个哈希地值&#xff0c;并将这个哈希地址作为储存改数据的地址&#xff0c;这样下次再查找这个数据时&#xff0c;只需要通过哈希函数再获取到该地址然后直接去拿就好这样就做到了不经过任何比较&#…

数学建模-评价类问题-优劣解距离法(TOPSIS)

1-AI带你认识TOPSIS&#x1f4d8; 一、TOPSIS 方法简介1. ​​基本定义&#xff1a;​​​​TOPSIS&#xff08;Technique for Order Preference by Similarity to an Ideal Solution&#xff09;​​&#xff0c;中文通常称为&#xff1a;•​​优劣解距离法​​•​​逼近理想…

Go协程:从汇编视角揭秘实现奥秘

&#x1f680; Go协程&#xff1a;从汇编视角揭秘实现奥秘 #Go语言 #协程原理 #并发编程 #底层实现 引用&#xff1a; 关于 Go 协同程序&#xff08;Coroutines 协程&#xff09;、Go 汇编及一些注意事项。 &#x1f31f; 前言&#xff1a;重新定义并发编程范式 在当今高并发…

MySQL 事务(重点)

MySQL 这个东西注定是可能会被多个用户/客户端来同时访问的&#xff0c;这是肯定的&#xff0c;MySQL 中存放的都是数据&#xff0c;数据可能有一个上层线程在用&#xff0c;也有可能另一个线程也要用...数据是被所有人共享的&#xff0c;所以就注定了 MySQL 这样的服务在一个时…

uniapp:h5链接拉起支付宝支付

场景&#xff1a;APP内点击支付宝支付&#xff0c;后台返回类似链接https://qr.alipay.com/bax***********c3050 通常做法是&#xff0c;使用plus.runtime.openURL(deeplink);先打开浏览器&#xff0c;浏览器会提示打开支付宝&#xff0c;之后是支付流程。现在可以省略跳转h5的…

吴恩达 Machine Learning(Class 3)

Week 11.1 K-means Cluster centroidK-means 是无监督学习中聚类算法的一种&#xff0c;核心在于更新聚类质心&#xff1b;首先将每个点分配给几个聚类质心&#xff0c;取决于那些点离哪个质心更近&#xff1b;然后将几个聚类质心移动到分配给他的所有点的平均值&#xff0c;不…

MyBatis 动态查询语句详解:让 SQL 更灵活可控

MyBatis 动态查询语句详解&#xff1a;让 SQL 更灵活可控 在日常的数据库操作中&#xff0c;我们经常会遇到需要根据不同条件拼接 SQL 语句的场景。比如查询用户时&#xff0c;可能需要根据姓名、年龄、性别等多个条件进行筛选&#xff0c;而这些条件往往是动态变化的 —— 有时…

Java基础语法three

一、一维数组一维数组初始化数据类型[] 数组名new 数据类型[数组长度]//动态初始化数据类型[] 数组名new 数据类型[]{值}//静态初始化数据类型[] 数组名{值}数组长度一旦确定&#xff0c;就不可更改。数组是序排序&#xff1b;数组属于引用数据类型的变量&#xff0c;数组的元素…

【数据结构】排序算法全解析:概念与接口

1.排序的概念及其运用 1.1 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的…

在 CentOS 7 上使用 LAMP 架构部署 WordPress

CentOS 7 LAMP 架构部署 WordPress全步骤本文将详细介绍如何在 CentOS 7 系统上通过 LAMP&#xff08;Linux Apache MariaDB PHP&#xff09;架构部署 WordPress 博客平台。 在CentOS 7上基于LAMP架构部署WordPress 一、系统基础配置 1. 修改主机名&#xff08;本机IP&#…