【源码】"拆" 网络请求库-Volley(中)

简介: Volley跟AsyncTask一样,都是老古董了,最早发布于2013年的Google I/O大会,初衷就是:让Android开发者少写重复的请求代码。

0x2、并发设计


像上面HttpUrlConnection的例子,每发起一次请求,都新起一个线程,太蠢了


  • 没复用线程,频繁创建销毁线程造成不必要的开销;


  • 没对最大线程数做一个限制,可能会造成过度资源竞争,系统使用率不高;


所以涉及到并发的开源项目,线程池 基本是没得走的了,再配个 任务队列 进出队列操作加锁,有时为了解耦,还会再拆出来一个 调度器死循环 访问 任务队列,取出任务交由线程池执行。


Volley是支持并发的,看下它是如何设计的,没有找到线程池初始化代码,倒是找到了 两个线程实现类


网络异常,图片无法展示
|


网络异常,图片无法展示
|


NetworkDispatcher 继承 Thread类,所以这里默认定义了 容量为4的线程数组,另外一个线程 CacheDispatcher。它们都在 RequestQueue → start() 中启动:


网络异常,图片无法展示
|


跟下start()的调用处 Volley → newRequestQueue


网络异常,图片无法展示
|


就是实例化RequestQueue的时候,就创建并开启了这些线程。


0x3、请求调度设计


调用 RequestQueue → add() 请求入队,跟下具体实现:


网络异常,图片无法展示
|


用到三个集合,根据对应注释推演出各种用途:


  • mCurrentRequests : HashSet → 正在处理的所有请求(包括等待和处理中)的集合;
  • mNetworkQueue : PriorityBlockingQueue → 非缓存请求队列;
  • mCacheQueue : PriorityBlockingQueue → 缓存请求队列;


入队比较简单,接着看下具体的调度流程,不难看出分成两类,走缓存(默认)和不走缓存,先看前者~


① 不走缓存的请求


NetworkDispatcher → run()


网络异常,图片无法展示
|


网络异常,图片无法展示
|


死循环拿队列的请求,处理请求后的结果流向有四个:


  • 请求处于取消状态 → request.finish("network-discard-cancelled");
  • 304且响应已解析过 → request.finish("not-modified");
  • 正常结束 → mDelivery.postResponse(request, response);
  • 异常结束 → mDelivery.postError(request, volleyError);


先跟下 Request → finish()


网络异常,图片无法展示
|


网络异常,图片无法展示
|


比较简单:移除集合中的请求,打日志,调用下请求结束的回调,接着看下后两个,跟下 ExecutorDelivery


网络异常,图片无法展示
|


跟下 mResponsePoster 初始化部分代码:


网络异常,图片无法展示
|


好吧,就是一个 执行器,负责将任务分发出去,因为后续操作在主线程操作,所以得用 Handler


接着,看下任务具体做了啥 ResponseDeliveryRunnable → run()


网络异常,图片无法展示
|


网络异常,图片无法展示
|


正常请求的流转还是很好理解的,接着看下走缓存请求的调度过程~


② 走缓存的请求


直接跟 CacheDispatcher → run(),同样是死循环,直接看 processRequest() 部分代码:


网络异常,图片无法展示
|


简单点说:有缓存且缓存没过期直接返会,其他情况把请求加到请求队列中。接着再看看缓存这块是咋设计的~

相关文章
|
4月前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
【7月更文挑战第31天】在网络数据的海洋中,使用Python的`requests`库构建网络爬虫就像探索未知的航船。HTTP协议指导爬虫与服务器交流,收集信息。HTTP请求包括请求行、头和体,响应则含状态行、头和体。`requests`简化了发送各种HTTP请求的过程。
83 4
|
2月前
|
JavaScript 前端开发 API
网络请求库 – axios库
网络请求库 – axios库
194 60
|
2月前
|
数据采集 JSON API
🎓Python网络请求新手指南:requests库带你轻松玩转HTTP协议
本文介绍Python网络编程中不可或缺的HTTP协议基础,并以requests库为例,详细讲解如何执行GET与POST请求、处理响应及自定义请求头等操作。通过简洁易懂的代码示例,帮助初学者快速掌握网络爬虫与API开发所需的关键技能。无论是安装配置还是会话管理,requests库均提供了强大而直观的接口,助力读者轻松应对各类网络编程任务。
115 3
|
2月前
|
机器学习/深度学习 JSON API
HTTP协议实战演练场:Python requests库助你成为网络数据抓取大师
在数据驱动的时代,网络数据抓取对于数据分析、机器学习等至关重要。HTTP协议作为互联网通信的基石,其重要性不言而喻。Python的`requests`库凭借简洁的API和强大的功能,成为网络数据抓取的利器。本文将通过实战演练展示如何使用`requests`库进行数据抓取,包括发送GET/POST请求、处理JSON响应及添加自定义请求头等。首先,请确保已安装`requests`库,可通过`pip install requests`进行安装。接下来,我们将逐一介绍如何利用`requests`库探索网络世界,助你成为数据抓取大师。在实践过程中,务必遵守相关法律法规和网站使用条款,做到技术与道德并重。
49 2
|
2月前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
在网络数据的海洋中,网络爬虫遵循HTTP协议,穿梭于互联网各处,收集宝贵信息。本文将从零开始,使用Python的requests库,深入解析HTTP协议,助你构建自己的网络爬虫帝国。首先介绍HTTP协议基础,包括请求与响应结构;然后详细介绍requests库的安装与使用,演示如何发送GET和POST请求并处理响应;最后概述爬虫构建流程及挑战,帮助你逐步掌握核心技术,畅游数据海洋。
67 3
|
2月前
|
数据采集 网络协议 API
HTTP协议大揭秘!Python requests库实战,让网络请求变得简单高效
【9月更文挑战第13天】在数字化时代,互联网成为信息传输的核心平台,HTTP协议作为基石,定义了客户端与服务器间的数据传输规则。直接处理HTTP请求复杂繁琐,但Python的`requests`库提供了一个简洁强大的接口,简化了这一过程。HTTP协议采用请求与响应模式,无状态且结构化设计,使其能灵活处理各种数据交换。
79 8
|
2月前
|
JSON API 开发者
Python网络编程新纪元:urllib与requests库,让你的HTTP请求无所不能
【9月更文挑战第9天】随着互联网的发展,网络编程成为现代软件开发的关键部分。Python凭借简洁、易读及强大的特性,在该领域展现出独特魅力。本文介绍了Python标准库中的`urllib`和第三方库`requests`在处理HTTP请求方面的优势。`urllib`虽API底层但功能全面,适用于深入控制HTTP请求;而`requests`则以简洁的API和人性化设计著称,使HTTP请求变得简单高效。两者互补共存,共同推动Python网络编程进入全新纪元,无论初学者还是资深开发者都能从中受益。
51 7
|
2月前
|
网络协议 Linux C++
超级好用的C++实用库之网络
超级好用的C++实用库之网络
44 0
WK
|
2月前
|
数据采集 XML 安全
常用的Python网络爬虫库有哪些?
Python网络爬虫库种类丰富,各具特色。`requests` 和 `urllib` 简化了 HTTP 请求,`urllib3` 提供了线程安全的连接池,`httplib2` 则具备全面的客户端接口。异步库 `aiohttp` 可大幅提升数据抓取效率。
WK
62 1
|
3月前
|
Java Android开发 开发者
Android项目架构设计问题之使用Retrofit2作为网络库如何解决
Android项目架构设计问题之使用Retrofit2作为网络库如何解决
65 0