当前位置: 首页 > news >正文

第一章 OkHttp 是怎么发出一个请求的?——整体流程概览

OkHttp相关的内容往往会在面试的过程中被一再提及,那么,OkHttp 到底是怎么把一句话 “帮我请求一下百度” 变成一次真正的网络通信?我们一步步来看吧

本章主要目标:
简单了解OkHttp的主体结构以及使用

1、场景想象

大家应该都点过外卖吧,我们不妨用外卖的视角来看下OkHttp的登场角色以及作用过程

OkHttp 概念外卖实体真实动作映射
OkHttpClient外卖平台总部拥有全部运力、系统、客服、仓库全局配置、连接池、线程池
Request下单小票用户 App 里下订单,含取货地址+送货地址+备注URL、Header、Body
Call一次“跑腿单”平台生成唯一单号,可立即派送或排队RealCall
Dispatcher外卖调度中心最多可派64辆车,每栋楼最多派5辆runningAsyncCalls / perHost limit
ConnectionPool电动车停靠点刚送完 A 栋的电动车不返仓,直接停楼下接下一单,5 分钟没人叫才回仓空闲连接 5 分钟回收
Interceptor 链5 道检查口①重试口(地址错?重派)
②加料口(默认给筷子)
③缓存口(店里现成?直接拿)
④取车口(给电动车)
⑤出单口(打印小票)
5 大拦截器
Response骑手送达后拍的照片+回执用户点确认收货,平台回传“已送达”照片Response 对象

2、流程概览

依照先前的设定,先简单借助图了解一下大概的流程,接着一步步拆解整个的过程
在这里插入图片描述
①首先,我们需要创建一个okHttpClient,这是一切的前提
②接着,作为客户,我们需要下单,此时Request便产生了,Request肯定需要一些我们的信息
newCall给到okHttpClient,那么就会借助Call,生成订单
④接下来,平台进行调度,Dispatcher给了两种方式,对应executeenqueue两种方式
⑤快递员出发需要层层检查,通过Interceptors来处理
⑥最终快递员将外卖送到用户手上或者放在门口拍照打卡,完成一次完整请求

3、代码层面

现在可能你对整个流程有更加生动的认识了,接下来,我们通过代码再来加深认识
这里我使用的是3.9.0的版本
build.gradle里面进行一下配置,好像现在的版本还有一个toml文件
在这里插入图片描述
在这里插入图片描述
此时,依赖配置完毕,同步一下

首先,看看我们平常直接使用的代码,仅仅是发起一个请求

try {                                                                                                              OkHttpClient okHttpClient = new OkHttpClient();                                                                Request request = new Request.Builder()                                                                        .url("https://movie.douban.com/j/chart/top_list?type=10&interval_id=100%3A90&action&start=20&limit=20").build();                                                                                              // 使用try-with-resources自动关闭Response,避免内存泄漏                                                                     try (Response response = okHttpClient.newCall(request).execute()) {                                            Log.d(TAG, "response=\n" + response.body().string());                                                      }                                                                                                              
} catch (Exception e) {                                                                                            e.printStackTrace();                                                                                           
}                                                                                                                  

这便是同步请求的写法,使用execute()进行请求
创建了OkHttpClient对象,并且给Request添加了信息,这里使用的是豆瓣电影的接口
使用newCall()创建请求,执行结果给到Response
注意,同步请求会阻塞当前的线程,直到结果返回,因此不会在主线程调用,否则很容易造成ANR,通常只会另外开辟线程使用或者用于测试代码

有一个初步的印象,我们再来看一看异步请求

OkHttpClient okHttpClient = new OkHttpClient();                                                                
Request request = new Request.Builder()                                                                        .url("https://movie.douban.com/j/chart/top_list?type=10&interval_id=100%3A90&action&start=20&limit=20").build();                                                                                              
okHttpClient.newCall(request).enqueue(new Callback() {                                                         @Override                                                                                                  public void onFailure(Call call, IOException e) {                                                          e.printStackTrace();                                                                                   }                                                                                                          @Override                                                                                                  public void onResponse(Call call, Response response) throws IOException {                                  try {                                                                                                  Log.d(TAG, "response=\n" + response.body().string());                                              } finally {                                                                                            response.close(); // 确保Response被关闭                                                                 }                                                                                                      }                                                                                                          
});                                                                                                                                                                                                                        

同样的业务需求,使用enqueue()则进行异步请求,不会阻塞,获得响应时回调
通常情况下都是采用异步请求的方式

在这里插入图片描述
这便是最简单的使用,通过response.body().string()获取响应结果

这两者主要的区别,在于是调用了execute()还是调用了equeue(),后面几章将会深入探讨里面的内容

参考
https://github.com/square/okhttp

http://www.lryc.cn/news/620252.html

相关文章:

  • 浏览器面试题及详细答案 88道(23-33)
  • 智能制造数字孪生最佳交付实践:打造数据融合×场景适配×持续迭代的数字孪生框架
  • 【LeetCode】6. Z 字形变换
  • 公用表表达式和表变量的用法区别?
  • Linux 5.15.189-rt87 实时内核安装 NVIDIA 显卡驱动
  • LeetCode215~ 234题解
  • ACWing 算法基础课-数据结构笔记
  • Leetcode题解:215,数组中的第k个最大元素,如何使用快速算法解决!
  • 把 Linux 装进“小盒子”——边缘计算场景下的 Linux 裁剪、启动与远程运维全景指南
  • C#+Redis,如何有效防止缓存雪崩、穿透和击穿问题
  • 联网车辆功能安全和网络安全的挑战与当前解决方案
  • OpenBMC中的BMCWeb:架构、原理与应用全解析
  • 直播美颜SDK开发实战:高性能人脸美型的架构与实现
  • C++调试革命:时间旅行调试实战指南
  • 图像优化:使用 Next.js 的 Image 组件
  • h5bench(4)
  • linux 内核 - 内存管理概念
  • Linux 服务部署:自签 CA 证书构建 HTTPS 及动态 Web 集成
  • GO学习记录四——读取excel完成数据库建表
  • [AXI5]AXI协议中awsize和awlen在Vector Atomic地址膨胀中的作用
  • Vue3从入门到精通: 3.5 Vue3与TypeScript集成深度解析
  • FPGA的PS基础1
  • 力扣(O(1) 时间插入、删除和获取随机元素)
  • 热门手机机型重启速度对比
  • 以鼠标位置为中心进行滚动缩放
  • 力扣top100(day02-03)--链表03
  • 修复运动模糊的视频用什么软件?快速解决方案分享
  • ECCV-2018《Variational Wasserstein Clustering》
  • AI工程化闭环法(AIEC – AI Engineering Cycle) 适合TRAE CURSOR CLAUDE等工具
  • Transformer 之自注意力机制(一)