Android中关于Volley的使用(七)认识 NetworkDispatcher 和 BasicNetwork

奥比中光Gemini335L SDK实战:从标定参数到3D点云转换 本文详细介绍了奥比中光Gemini 335L深度相机的SDK实战应用,重点讲解如何跳过繁琐的棋盘格标定,直接调用出厂预标定参数实现高效的3D点云转换。通过解析内参、外参获取及四种核心坐标转换模式,并结合OpenCV等工具,指导开发者快速将相机集成到机器人抓取、三维测量等项目中,实现开箱即用的3D视觉解决方案。 阅读详情

Volley最主要的功能其实就是跟网络打交道,然后从网络中获取相对应的数据,虽然有缓存线程(CacheDispatcher),但是如果缓存中没有对应的记录的话,还是会将其扔到网络队列中,由网络线程(NetworkDispatcher)来干活。

那么就看看NetworkDispatcher都干什么吧,如下:

    public void run() {
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        Request<?> request;
        while (true) {
            try {
                // 从队列中获取一个请求,如果没有请求,则会一直阻塞
                request = mQueue.take();
            } catch (InterruptedException e) {
                // We may have been interrupted because it was time to quit.
                if (mQuit) {
                    return;
                }
                continue;
            }

            try {
                request.addMarker("network-queue-take");

                // 判断请求有没有取消,如果取消,则不必再继续
                if (request.isCanceled()) {
                    request.finish("network-discard-cancelled");
                    continue;
                }

                addTrafficStatsTag(request);

                // 调用mNetwork去跟网络打交道
                NetworkResponse networkResponse = mNetwork.performRequest(request);
                request.addMarker("network-http-complete");

                // 如果服务器返回一个未修改(304)的响应,并且这个请求已经发送过响应对象,不需要再继续,因为没改过
                if (networkResponse.notModified && request.hasHadResponseDelivered()) {
                    request.finish("not-modified");
                    continue;
                }

                // 分析响应的数据,返回Response对象
                Response<?> response = request.parseNetworkResponse(networkResponse);
                request.addMarker("network-parse-complete");

                // 根据request的shouldCache字段来判断是不是需要缓存,如果需要,则将其放到mCache中。
                if (request.shouldCache() && response.cacheEntry != null) {
                    mCache.put(request.getCacheKey(), response.cacheEntry);
                    request.addMarker("network-cache-written");
                }

                // 调用 mDelivery将Response对象传回主线程进行UI的更新。
                request.markDelivered();
                mDelivery.postResponse(request, response);
            } catch (VolleyError volleyError) {
                parseAndDeliverNetworkError(request, volleyError);//有错误,也会调用到mDelivery,将错误信息传回到主线程,进行提示
            } catch (Exception e) {
                VolleyLog.e(e, "Unhandled exception %s", e.toString());
                mDelivery.postError(request, new VolleyError(e));
            }
        }
    }
网络线程(NetworkDispatcher)主要做了几件事情:

1)调用 mQueue的take()方法从队列中获取请求,如果没有请求,则一直阻塞在那里等待,直到队列中有新的请求到来。

2)判断请求有没有被取消,如果被取消,则重新获取请求。

3)调用Network对象将请求发送到网络中,并返回一个 NetworkResponse对象。

4)调用请求的pareseNetworkResonse方法,将NetworkResponse对象解析成相对应的Response对象。

5)判断请求是否需要缓存,如果需要缓存,则将其Response中cacheEntry对象放到缓存mCache中。

6)调用 mDelivery将Response对象传到主线程中进行UI更新。

另外有一个要注意的就是,在Volley中,默认是有4个网络线程同时在跑的,而对应的缓存线程,则只有一个。

从上面的代码中,可以看到,网络线程其实是调用 Network对象去实现跟网络进行沟通的,而在Volley中,默认的Network实现类,则是BasicNetwork类。

下面我们就看看它的performRequest方法:

   public NetworkResponse performRequest(Request<?> request) throws VolleyError {
        ...
        while (true) {
            HttpResponse httpResponse = null;
            byte[] responseContents = null;
            Map<String, String> responseHeaders = new HashMap<String, String>();
            try {
                // 添加头部信息
                Map<String, String> headers = new HashMap<String, String>();
                addCacheHeaders(headers, request.getCacheEntry());
                httpResponse = mHttpStack.performRequest(request, headers);//调用HttpStack对象去网络中获取数据
                StatusLine statusLine = httpResponse.getStatusLine();
                int statusCode = statusLine.getStatusCode();

                responseHeaders = convertHeaders(httpResponse.getAllHeaders());
                // 从响应的状态行获取状态编码,如果是304(未修改),说明之前已经取过数据了,那么就直接利用缓存中的数据,构造一个NetworkResonse对象
                if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
                    return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED,
                            request.getCacheEntry() == null ? null : request.getCacheEntry().data,
                            responseHeaders, true);
                }

                // 有些响应是不带内容的,比如响应状态编码是204的话,添加一个空的byte作为内容,后面好统一处理。
                if (httpResponse.getEntity() != null) {
                  responseContents = entityToBytes(httpResponse.getEntity());
                } else {
                  // Add 0 byte response as a way of honestly representing a
                  // no-content request.
                  responseContents = new byte[0];
                }
                ...//忽略了一些log的处理。
                return new NetworkResponse(statusCode, responseContents, responseHeaders, false);
            } ...//这里忽略了一些异常处理
            } catch (IOException e) {
                ...
                if (responseContents != null) {
                    networkResponse = new NetworkResponse(statusCode, responseContents,
                            responseHeaders, false);
                    if (statusCode == HttpStatus.SC_UNAUTHORIZED ||
                            statusCode == HttpStatus.SC_FORBIDDEN) {
                        attemptRetryOnException("auth",
                                request, new AuthFailureError(networkResponse));//这里会根据Volley的Retyr机制进行重新获取。
                    } else {
                        throw new ServerError(networkResponse);
                    }
                } else {
                    throw new NetworkError(networkResponse);
                }
            }
        }
    }

BasicNetwork做的事情如下:

1)对于已经有缓存的请求,添加其头部信息,如下:

    private void addCacheHeaders(Map<String, String> headers, Cache.Entry entry) {
        // If there's no cache entry, we're done.
        if (entry == null) {
            return;
        }

        if (entry.etag != null) {
            headers.put("If-None-Match", entry.etag);
        }

        if (entry.serverDate > 0) {
            Date refTime = new Date(entry.serverDate);
            headers.put("If-Modified-Since", DateUtils.formatDate(refTime));
        }
    }

2)调用 HttpStack 对象去网络中获取数据,返回httpResonse 对象。

3)根据状态编码来返回不同的Response对象,如304(未修改)就返回缓存中的数据,如果不是,则根据响应中的数据,重新构造一个NetworkResponse对象。

4)BasicNetwork实现了重试的机制,如果第一次从网络获取失败,默认会重新再尝试一次,如果失败,则会将Error返回,默认的实现类是DefaultRetryPolicy类。


在Network中返回的NetworkResponse对象,会在NetworkDispatcher中由具体的Request(比如ImageRequest,JsonRequest)类来进行解析,再最后返回给UI线程。

结束!

关于缓存线程的介绍:

Android中关于Volley的使用(六)认识 CacheDispatcher

MFC Tab Control控件完全指南:从基础使用到高级定制 本文详细介绍了MFC中TabControl控件的使用方法和高级技巧。主要内容包括:1) TabControl基础属性设置与绑定;2) 样式定制和外观自定义;3) 创建派生类实现扩展功能;4) 动态页面管理和子对话框控制;5) 高级功能如标签拖拽排序和右键菜单。通过完整代码示例,展示了从基本应用到复杂场景的实现方案,包括多标签页管理、自定义绘制、动态添加/删除标签等核心功能,为MFC开发者提供了全面的TabControl开发指南。 阅读详情

相关推荐

给硬件工程师的UCIe软件配置入门:从寄存器表到实战调试,一篇讲透

本文为硬件工程师提供UCIe软件配置的全面指南,从寄存器表解析到实战调试技巧,涵盖链路训练、错误排查等关键环节。通过详细代码示例和分层诊断法,帮助工程师快速掌握UCIe寄存器访问机制,提升异构集成开发效率。

weixin_30268921的博客 313

Ubuntu20自动开机加载/关机保存iptables配置

Ubuntu20已不再支持/etc/network/interfaces配置文件。依托于interfaces配置文件的pre-up/post-up hook脚本也不再支持。替代品Netplan目前也不支持前述的hook脚本。要想实现hook脚本的功能目前可使用networkd-dispatcher来达成。注意在networkd-dispatcher中hook的功能是异步的。详细信息可参考man networkd-dispatcher。 文章目录 一、ifupdown hook功能实现 1. 使用net

yunlin2000的专栏 2788

VC Spyglass:Lint实战指南之TCL脚本自动化解析

本文详细介绍了如何利用TCL脚本实现VC Spyglass Lint检查的自动化流程。通过实战指南,从基础脚本编写到高级参数化技巧,帮助数字IC设计工程师摆脱手动操作,提升验证效率,并实现与CI/CD流程的集成。

h3i4j的博客 796

Android源码分析之理解Volley

0 参考链接 volley官网 手撕 Volley Volley全方位解析,带你从源码的角度彻底理解 Android Volley完全解析(四),带你从源码的角度理解Volley Android 面试之常用开源库 HTTP权威指南笔记 Java并发编程:阻塞队列 1 前言   Volley 是 Google 推出的轻量级 Android 异步网络请求框架和图片加载框架。在 ...

chenliguan的博客 1256

DSH-Work:一个让DeepSeek下载即用的Harness客户端

使用大模型工具时,环境配置往往比模型本身更让人头疼。DeepSeek Harness作为一类封装层,将模型调用、上下文管理、参数控制等复杂细节统一收拢,对外提供简洁操作入口。开源的DSH-Work正是这样一款Harness客户端,它通过自带运行时与保守默认配置,实现了下载即用、免配环境的目标,让使用者无需掌握Python、CUDA等专业知识即可快速连接DeepSeek云端或本地服务。对于非技术背景的用户,它降低了AI工具的使用门槛;对于开发者,它把时间从环境排错中解放出来,更专注于提示词调优与工作流设计。无

weixin_29048309的博客 343

软考中级信息系统监理师(第二版)-第21章基础设施工程监理

由于网络信息技术的飞速发展,变化日新月异,网络设计不但要保证目前网络传输容量的要求,也要考虑今后网络的发展,满足当前以及今后相当一段时间内的网络需求,便于向新技术的升级和衔接,同时又需要保护原有的投资。通用布缆系统工程中,承建单位的竣工文档主要包括以下内容:承建合同,招标文件,投标文件,设计方案,工程实施组织设计方案,工程施工报告,隐蔽工程记录,变更记录,自测报告,信息点分布图(表),园区、楼宇、水平配线表,楼层平面图及无线设备点位图,无线设备信息表,竣工图纸等。多排安装时,列间距不应小于1200mm。

2301_78583973的博客 1400

1 | Nessus使用

Nessus

u013916029的博客 2979

STM32单片机入门学习(六)-光敏传感器控制LED

光敏传感模块一DO端接B13,GND接GND,VCC接VCC,AO不接。LED负极接B12,正极接VCC。

指尖魔法师 4368

Web漏洞扫描篇-Nessus使用

选择“Basic Network Scan”,配置项目名称还有对项目的描述,以及最重要的目标IP地址。点击"Plugins"可以查看我们可能或者需要用到的插件。然后,点击“New Scan”建立一个新的扫描。Web漏洞扫描篇-Nessus使用。首先打开Nessus。

weixin_53221940的博客 1225

QT快速配置MSVC2017编译环境(3分钟极简指南)

本文提供了一份3分钟极简指南,帮助开发者快速配置QT的MSVC2017编译环境。通过断网安装、精准勾选组件和配置QT Creator编译器路径等步骤,大幅提升QT开发效率。MSVC2017作为Windows平台高性能C++编译器,特别适合处理大型QT项目,编译速度优势明显。

weixin_30399821的博客 503

从零手搓大模型(一)文本如何变成 LLM 的输入

本文介绍了从原始文本到LLM输入向量的完整处理流程。主要内容包括: 文本预处理:通过正则表达式将原始文本分割成token列表,处理标点和空格。 词表构建:创建token到ID的映射字典(vocabulary),这是文本数字化的关键步骤。 简单tokenizer实现:封装了编码(encode)和解码(decode)功能,完成文本与token ID的相互转换。 处理流程:原始文本 → 分词 → token ID → 嵌入表示 → 最终输入向量。 数据形状变化:从字符串逐步转换为(batch_size, cont

echo的博客 998

Android中关于Volley的使用(四)认识 NetworkDispatcher 和 BasicNetwork

Volley最主要的功能其实就是跟网络打交道,然后从网络中获取相对应的数据,虽然有缓存线程(CacheDispatcher),但是如果缓存中没有对应的记录的话,还是会将其扔到网络队列中,由网络线程(NetworkDispatcher)来干活。 那么就看看NetworkDispatcher都干什么吧,如下: [java] view plaincopy

junjianzhang的专栏 498

YOLO26优化:AAAI2026 | 融合PartialNet Block的C3k2-YOLO高效目标检测网络 | 轻量化涨点设计

PartialNet Block 结合YOLO26的C3k2模块,进行二次创新。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 592

[Android]Volley源码分析(四)

上篇中有提到NetworkDispatcher是通过mNetwork(Network类型)来进行网络访问的,现在来看一下关于Network是如何进行网络访问的。 Network部分的类图: Network有一个实现类BasicNetwork,它有一个mHttpStack的属性,实际的网络请求是由这个mHttpStack来进行的,看BasicNetwork的performRe...

132

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Android应用开发:网络工具——Volley(二)

本文从Volley源码角度来分析一下,一个网络请求在Volley中是如何运作的,也可以看作网络请求在Volley中的生命周期。

Feed Technology 7672

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Volley详解(五)——网络(Network)

概述本篇介绍网络相关的类,包括Network,BasicNetwork,NetworkDispatcher。

howard_90的专栏 750

Volley源码解析

从newRequestQueue进行入手来进行一步步分析源码的流程 public static RequestQueue newRequestQueue(Context context) { return newRequestQueue(context, null); } public static RequestQueue newRequestQueue(Context c

拼搏的少年的博客 664

Volley源码解析(二)

volley源码——网络解析

zjm0518的博客 683

Volley框架源码详细解析

作为android开发者,volley这个框架应该不陌生,它有很多优点。比如通信速度快,代码编写简单,能取消请求,能并发,能缓存等等。 volley为什么这么好用呢,今天我们来看看源码,分析分析原理。 从使用开始说起,分三步: 1. RequestQueue queue = Volley.newRequestQueue(this); 2. StringRequest sq = new

zyy8155454的专栏 362

Volley框架解析(四)-----Network接口及其默认实现类解析

Volley框架解析(四)—–Network接口及其默认实现类解析1. 前言(可直接无视跳过    前面的三篇Volley框架解析文章已经从Volley对外暴露的接口Volley.java开始,向下慢慢深入到了RequestQueue.java,这个Volley中比较核心的类,然后又分析了Volley中负责主要request调度工作的两类Dispatcher,NetworkDispatcher以及C

凹凸曼哒小乖兽 1779

Android 学习笔记之Volley开源框架解析(四)

    学习内容: 1.NetWorkDispatcher网络请求线程调度... 2.NetWork网络请求抽象类... 3.BasicNetWork网络请求抽象类的具体实现... 4.NetWorkResponse接收网络请求返回的响应... 5.ResponseDelivery请求分配抽象类... 6.ExecutorDelivery请求分配的具体实现类...     上一...

weixin_34041003的博客 144

第四:Nessus-基本网络扫描实例(Basic Network Scan)(四)

Nessus基本网络扫描操作指南 本文详细介绍了Nessus漏洞扫描工具的基本网络扫描功能及操作流程。主要内容包括:主机发现、端口扫描、服务识别、漏洞检测等核心扫描原理;从新建扫描项目、配置参数、设置认证方式到执行扫描的完整步骤;以及扫描结果查看、漏洞分析和报告导出等后续操作。文章还提供了扫描过程中的注意事项,如Linux系统需要配置SSH认证、邮件通知设置等实用技巧,并配有操作界面截图辅助说明。通过本指南,用户可以快速掌握使用Nessus进行网络漏洞扫描的标准流程和方法。

欢迎来到本博客! 737

android接口请求接口返回404,android - Unexpected response code 404 for api.jsonbin POST request - Stack Overf...

I want to POST a new employee into that.This is what I did:activity_main.xmlxmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match...

weixin_36111764的博客 829

Nessus 漏洞扫描工具

Nessus是一种广泛使用的漏洞扫描工具,由Tenable Network Security开发。它用于自动化地扫描网络设备、计算机系统、软件应用程序等,以发现安全漏洞和配置错误。Nessus非常适合企业环境,用于评估和增强网络安全。

探测??? 764

渗透测试技术_Nessus工具(二) _漏洞扫描工具 Nessus的使用教程

漏洞扫描工具 Nessus的使用教程 1、Nessus使用教程 1.1、Nessus登录 在浏览器中访问:https://{服务器IP}:8834 例如访问:https://10.1.1.191:8834/ 输入你注册的账号密码进行登录,例如:nessus_casb/liaxx,进入主页面。 1.2、新建1个主机扫描 1.2.1、点击右上角的”New Scan”新建一个扫描 1.2.2、选择“Basic Network Scan”,进行配置项目名称,对项目的描述,以及最重要的目标I.

fen_fen的专栏 5720
上一篇: Android中关于Volley的使用(六)认识 CacheDispatcher
下一篇: Android学习小Demo(16)Android中使用已存在数据的SqliteDatabase
linmiansheng
博客等级 码龄20年 507粉丝 111原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值