【源码】"拆" 网络请求库-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月前
|
C++
基于Reactor模型的高性能网络库之地址篇
这段代码定义了一个 InetAddress 类,是 C++ 网络编程中用于封装 IPv4 地址和端口的常见做法。该类的主要作用是方便地表示和操作一个网络地址(IP + 端口)
283 58
|
4月前
|
网络协议 算法 Java
基于Reactor模型的高性能网络库之Tcpserver组件-上层调度器
TcpServer 是一个用于管理 TCP 连接的类,包含成员变量如事件循环(EventLoop)、连接池(ConnectionMap)和回调函数等。其主要功能包括监听新连接、设置线程池、启动服务器及处理连接事件。通过 Acceptor 接收新连接,并使用轮询算法将连接分配给子事件循环(subloop)进行读写操作。调用链从 start() 开始,经由线程池启动和 Acceptor 监听,最终由 TcpConnection 管理具体连接的事件处理。
171 2
|
4月前
基于Reactor模型的高性能网络库之Tcpconnection组件
TcpConnection 由 subLoop 管理 connfd,负责处理具体连接。它封装了连接套接字,通过 Channel 监听可读、可写、关闭、错误等
156 1
|
4月前
|
负载均衡 算法 安全
基于Reactor模式的高性能网络库之线程池组件设计篇
EventLoopThreadPool 是 Reactor 模式中实现“一个主线程 + 多个工作线程”的关键组件,用于高效管理多个 EventLoop 并在多核 CPU 上分担高并发 I/O 压力。通过封装 Thread 类和 EventLoopThread,实现线程创建、管理和事件循环的调度,形成线程池结构。每个 EventLoopThread 管理一个子线程与对应的 EventLoop(subloop),主线程(base loop)通过负载均衡算法将任务派发至各 subloop,从而提升系统性能与并发处理能力。
268 3
|
4月前
基于Reactor模式的高性能网络库github地址
https://github.com/zyi30/reactor-net.git
121 0
|
4月前
基于Reactor模型的高性能网络库之Poller(EpollPoller)组件
封装底层 I/O 多路复用机制(如 epoll)的抽象类 Poller,提供统一接口支持多种实现。Poller 是一个抽象基类,定义了 Channel 管理、事件收集等核心功能,并与 EventLoop 绑定。其子类 EPollPoller 实现了基于 epoll 的具体操作,包括事件等待、Channel 更新和删除等。通过工厂方法可创建默认的 Poller 实例,实现多态调用。
292 60
|
4月前
|
安全 调度
基于Reactor模型的高性能网络库之核心调度器:EventLoop组件
它负责:监听事件(如 I/O 可读写、定时器)、分发事件、执行回调、管理事件源 Channel 等。
285 57
|
4月前
基于Reactor模型的高性能网络库之时间篇
是一个用于表示时间戳(精确到微秒)**的简单封装类
197 57
|
4月前
|
缓存 索引
基于Reactor模式的高性能网络库之缓冲区Buffer组件
Buffer 类用于处理 Socket I/O 缓存,负责数据读取、写入及内存管理。通过预分配空间和索引优化,减少内存拷贝与系统调用,提高网络通信效率,适用于 Reactor 模型中的异步非阻塞 IO 处理。
185 3
|
3月前
|
机器学习/深度学习 算法 数据库
基于GoogleNet深度学习网络和GEI步态能量提取的步态识别算法matlab仿真,数据库采用CASIA库
本项目基于GoogleNet深度学习网络与GEI步态能量图提取技术,实现高精度步态识别。采用CASI库训练模型,结合Inception模块多尺度特征提取与GEI图像能量整合,提升识别稳定性与准确率,适用于智能安防、身份验证等领域。
下一篇
oss云网关配置