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

最新版volley-6.0.jar google出的最新版volley的jar包,可以直接导入工程使用。 立即下载

当调用 RequestQueue的 add()方法添加 Request 的时候,会根据请求的一个参数 shouldCache,来判断要不要去缓存中查询,如果是去缓存中查询,那么就会把请求放到CacheQueue中,如下:

                mWaitingRequests.put(cacheKey, null);
                mCacheQueue.add(request);

这个时候,线程CacheDispatcher其实已经在跑了,到它的run方法中来看一下:

    public void run() {
        if (DEBUG) VolleyLog.v("start new dispatcher");
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

        // 初始化缓存
        mCache.initialize();

        while (true) {
            try {
                // 从缓存队列中获取一个请求
                final Request<?> request = mCacheQueue.take();
                request.addMarker("cache-queue-take");

                // 如果请求已经被取消,则重新获取请求
                if (request.isCanceled()) {
                    request.finish("cache-discard-canceled");
                    continue;
                }

                // 根据request的cacheKey从缓存中得到对应的记录
                Cache.Entry entry = mCache.get(request.getCacheKey());
                if (entry == null) {
                    request.addMarker("cache-miss");
                    // 这里说明缓存中没有对应的记录,那么需要去网络中获取,那么就将它放到Network的队列中
                    mNetworkQueue.put(request);
                    continue;
                }

                // 如果缓存中有记录,但是已经过期了或者失效了,也需要去网络获取,放到Network队列中
                if (entry.isExpired()) {
                    request.addMarker("cache-hit-expired");
                    request.setCacheEntry(entry);
                    mNetworkQueue.put(request);
                    continue;
                }

                // 如果上面的情况都不存在,说明缓存中存在这样记录,那么就调用request的parseNetworkResponse方法,获取一个响应Response
                request.addMarker("cache-hit");
                Response<?> response = request.parseNetworkResponse(
                        new NetworkResponse(entry.data, entry.responseHeaders));
                request.addMarker("cache-hit-parsed");

                if (!entry.refreshNeeded()) {
                    // 缓存记录,不需要更新,那么就直接调用mDelivery,传回给主线程去更新。
                    mDelivery.postResponse(request, response);
                } else {
                    // 还存在这样一种情况,缓存记录存在,但是它约定的生存时间已经到了(还未完全过期,叫软过期),可以将其发送到主线程去更新
                    // 但同时,也要从网络中更新它的数据
                    request.addMarker("cache-hit-refresh-needed");
                    request.setCacheEntry(entry);

                    // Mark the response as intermediate.
                    response.intermediate = true;

                    // 将其传回主线程的同时,将请求放到Network队列中。
                    mDelivery.postResponse(request, response, new Runnable() {
                        @Override
                        public void run() {
                            try {
                                mNetworkQueue.put(request);
                            } catch (InterruptedException e) {
                                // Not much we can do about this.
                            }
                        }
                    });
                }

            } catch (InterruptedException e) {
                // We may have been interrupted because it was time to quit.
                if (mQuit) {
                    return;
                }
                continue;
            }
        }
    }

缓存线程(CacheDispatcher)主要做了几件事情:

1)初始化本地缓存

2)开始一个无限的循环,调用 mCacheQueue的take方法,来获得一个请求,而mCacheQueue是一个BlockingQueue,也就是说,当队列中没有请求的时候,take方法就会一直阻塞在这里,等待队列中的请求,而一旦队列中有新的请求进来了,那么它就会马上执行下去。

    /** The queue of requests coming in for triage. */
    private final BlockingQueue<Request<?>> mCacheQueue;

    /** The queue of requests going out to the network. */
    private final BlockingQueue<Request<?>> mNetworkQueue;

3)判断请求是否已经取消,如果已经被取消了,则不需要再走下去。

4)根据请求的CacheKey去缓存中寻找相对应的记录,如果找不到对应的记录,或者对应的记录过期了,则将其放到NetworkQueue队列中。

5)缓存中存在相对应的记录,那么调用每个请求具体的实现方法 parseNetworkResponse函数,根据具体的请求去解析得到对应的响应Response对象。

6)获得Response对象之后,还会再进行判断这个请求是不是进行一次网络的更新,这是根据记录的soft-ttl (time-to-live)属性,如下:

        /** True if the entry is expired. */
        public boolean isExpired() {
            return this.ttl < System.currentTimeMillis();
        }

        /** True if a refresh is needed from the original data source. */
        public boolean refreshNeeded() {
            return this.softTtl < System.currentTimeMillis();
        }

从这里也可以看到,expired的判断跟refreshNeed的判断是两个字段,一个是ttl,一个是softTtl。

如果需要进行更新,那么就会在发送响应结果回主线程更新的同时,再将请求放到NetworkQueue中,从网络中更新请求对应的数据。如果不需要,则直接将结果调用mDelivery传回主线程进行UI的更新。

CacheDispatcher做的事情并不多,因为Volley主要的功能其实还是跟网络打交道,所以主要的实现,其实还是NetworkDispatcher。

结束!


volley源码15/6/29版本 立即下载

相关推荐

矩阵LED和矩阵按键

先说矩阵LED,如图: 下面以行几、列几的表达方法说明 三极管可以当做开关使用 由图可知,如果想让一个LED亮,那么它对应的行和列的三极管都要导通。如果这个矩阵每次只亮一个LED,那么正常写程序没问题。 如果我们想让LED1和LED6亮,其他灯不亮,则需要开启行1、行2、列1、列2,随之带来的问题就是LED2和LED5也会跟着亮起来。 解决方法类似于扫描,因为单片机运行速度很快,可以在很短的时间内开关数次而肉眼看不到。所以我们可以每次只亮一列(排)灯,亮单位时间后关掉同时开启另外一列(排),如此四次一循环

qq_46615634的博客 5789

volley源码解析(四)--CacheDispatcher从缓存中获取数据

从上一篇文章我们已经知道,现在要处理的问题就是CacheDispatcher和NetworkDispatcher怎么分别去缓存和网络获取数据的问题,这两个问题我分开来讲。 但是首先说明的是,这两个问题其实是有联系的,当CacheDispatcher获取不到缓存的时候,会将request放入网络请求队列,从而让NetworkDispatcher去处理它; 而当NetworkDispatcher获

crazychen的专栏 2454

手把手教你用Three.js+Vue打造3D机房可视化系统(附完整代码)

本文详细介绍了如何使用Three.js与Vue 3构建企业级3D机房可视化系统。从技术选型、项目架构设计到3D场景构建、设备建模与渲染策略,提供了完整的开发方案和实战代码。重点讲解了如何实现设备状态实时监控、交互操作与性能优化,帮助开发者快速掌握3D可视化开发的核心技术。

ttt77的博客 315

Android Volley完全解析(一),初识Volley的基本用法

我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据。Android系统中主要提供了两种方式来进行HTTP通信,HttpURLConnection和HttpClient,几乎在任何项目的代码中我们都能看到这两个类的身影,使用率非常高。Android开发团队也是意识到了有必要将HTTP的通信操作再进行简单化,于是在2013年Google I/O大会上推出了一个新的网络通信框架——Volley。Volley可是说是把AsyncHttpC

郭霖的专栏 36万+

Vivado IP核综合失败别慌:除了打补丁,这个TCL命令也能救急(以Video Frame Buffer为例)

本文详细解析了Vivado IP核综合失败的排查方法,特别是针对Video Frame Buffer Read IP的常见问题。从补丁安装到深入分析DCP文件生成机制,再到使用强大的TCL命令`foreach ip_in_proj [get_ips] {compile_c [get_ips $ip_in_proj]}`强制重编译,提供了一套完整的解决方案。帮助开发者快速定位并解决IP核综合失败问题,确保项目顺利进行。

weixin_30892889的博客 423

Python OpenCV基于颜色通道分离法去除图片中的红色印章

最近一段时间的工作都是研究如何去除图片中的红色印章,在网上查找了大量的大佬写过的方法,发现大多数是采取颜色通道分离法来做,并且效果还不错。站在前人的肩膀上,我又做了些许调整,谈不上是改进,但是能应对更对的情况总还是好的,特此记录。 拿发票做例子,印章相较于其它部分最大的不同就是印章是红色的,而其它部分不是(这是一句废话)。 那么第一步当然就是将红色分离出来,这一步可以采用Python第三方库OpenCV里的 cv2.split()方法,该方法是把RGB图像的三个通道拆分开来,得...

wl_Honest的博客 1万+

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

当调用 RequestQueue的 add()方法添加 Request 的时候,会根据请求的一个参数 shouldCache,来判断要不要去缓存中查询,如果是去缓存中查询,那么就会把请求放到CacheQueue中,如下: [java] view plaincopy mWaitingRequests.put(cacheKey, null);  

junjianzhang的专栏 496

Android网络框架volley学习(六)调度器CacheDispatcher简析

在前面的分析文章中,我们了解到,当发起一个请求时,首先加入到请求队列中,请求队列中是如何工作的呢?它会首先去缓存队列中取,如果不符合的话另开网络线程去执行这个请求操作。 源码路径RequestQueue#start /** * Starts the dispatchers in this queue. */ public void start() {

ostracod 668

PINN驱动的3D不可压缩流场重建——从稀疏2D2C观测到完整物理场反演——含源码实现

多尺度融合策略在此发挥作用:高分辨率的2D2C数据用于约束平面内的精细结构,而低分辨率的3D3C数据提供第三维度的粗尺度信息。迁移学习架构在此发挥关键作用。这种策略在湍流封闭模型构建中尤为有效,其中RANS提供的平均流场与DNS的雷诺应力数据融合,显著提升了分离流的预测精度。在稀疏数据场景下,注意力权重根据观测数据的分布动态调整,强化数据缺失区域的物理约束,同时避免过拟合于观测点。这种机制与自适应采样的结合,实现了计算效率与重建精度的平衡,在仅保留约百分之十关键节点的情况下,仍能保持高物理一致性。

u012133341的博客 136

十七、SAP-采购订单(STO)

业务逻辑、功能讲解、图文解析、章节总结

m0_72403327的博客 2067

Android网络框架-Volley(三) CacheDispatcher和NetworkDispatcher源码分析

在Android网络框架-Volley(一) 工作原理分析 中的流程图中我们知道Volley工作是有三个线程的:主线程、缓存线程和网络线程。这些线程的工作是建立在RequestQueue上的,上一篇文章 Android网络框架-Volley(二) RequestQueue源码分析以及建立一个RequestQueue 中我们分析了RequestQueue的源码以及最佳使用方式,这篇文章我们来分析

阿拉灯神灯的专栏 2059

Open3D 合并两个点云【2025最新版】

两个点云中的数据连接,博客长期更新,本文最新更新时间为:2025年4月26日。

点云侠的博客 7435

Android最火的框架系列(四)Volley

其实,本来不想写Volley的,由于前面写了一篇如何使用Eclipse搭建Android服务端的博客,今天,我们尝试用Volley去访问一下。其实,Volley已经不算是很火的网络请求框架了,Volley算是一个比较适合新手的网络请求库。Volley现在在Github上仅有2.3k的star,现在用的多的是Retrofit+okhttp。但是,Volley在某些场景下,使用起来还是挺不错...

zhaojun的博客 2万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Android网络编程(四)从源码解析Volley

从上图可以看到volley分为三个线程,分别是主线程、缓存调度线程、和网络调度线程,首先请求会加入缓存队列,如果发现可以找到相应的缓存结果就直接读取缓存并解析,然后回调给主线程;如果在缓存中没有找到结果,则将这条请求加入到网络队列中,然后发送HTTP请求,解析响应并写入缓存,并回调给主线程。

Android进阶三部曲 - 刘望舒 1万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Volley框架简介

一、引言 虽然网上已经有很多大神、高手都写过了类似的帖子,但作为新人,必须要走模仿的道路,再考虑超越,因此学习大神的笔记,记录自己的理解,是一个菜鸟走向成功的必经之路啊。如签名所言,记录自己摸爬滚打的经历,享受不悔的青春。废话不多说,言归正传。 二、Volley是什么? Volley是 Google 推出的 Android 异步网络请求框架和图片加载框架。 三、Volley的主要特性 (

不悔的青春 4018

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Android中的volley_8_缓存调度线程CacheDispatcher

CacheDispatcher也是volley的核心类之一。 跟NetworkDispatcher一样,CacheDispatcher也是一个线程,该线程的作用就是从缓存队列中获取request,根据request的cacheKey从缓存Cache内获取该request的响应。在RequestQueue内,会对所有的request进行分发,如果一个request是可以被缓存的,那么就会分发到缓存

vvzhouruifeng的博客 687

Android常用开源网络框架(一)—— Volley篇

Android常用开源网络框架 在Android开发中,网络请求是最重要的模块之一,Android中大部分网络请求使用的是HTTP连接,包括原生的HttpClient和HttpUrlConnection两种访问网络方式。需要注意的是,HttpClient方式在Android6.0以后,很多类已经不支持了。 目前主流的开源网络框架,主要有OkHttp,Volley,Retrofit三种,我本人在短暂...

步步小猫的博客 738

Volley源码学习(三):线程处理request,类CacheDispatcher,NetworkDispatcher,ExecutorDelivery

一.源码解析 volley处理request的流程:当调用RequestQueue的add(request)方法时,会进行一系列逻辑判断:如先从cache获取,没有或者过期,再从网络获取。这是通过将request添加到CacheQueue和NetworkQueue里,最终是由线程类CacheDispatcher,NetworkDispatcher进行相应处理的。 1.类CacheDis

qq_27601757的博客 235

Android Volley 源码解析(一),网络请求的执行流程

最后,如果大伙有什么好的学习方法或建议欢迎大家在评论中积极留言哈,希望大家能够共同学习、共同努力、共同进步。

2401_84123056的博客 921

Volley源码解析

人人都说Volley写的非常优秀,今天我们就打开volley的源码,来看看volley是怎么实现网络请求的,首先,我们从刚开始使用入手mRequestQueue = Volley.newRequestQueue(App.getInstance());跟进代码,Volley.newRequestQueue,public static RequestQueue newRequestQueue(Conte

Loader's Blog 6813

【网络编程】Volley使用与源码分析

在2013年Google I/O大会上推出了一个新的网络通信框架Volley。Volley既可以访问网络取得数据,也可以加载图片,并且在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。

xoliu的博客 1151
上一篇: LeetCode(一)关于GrayCode的实现
下一篇: Android中关于Volley的使用(七)认识 NetworkDispatcher 和 BasicNetwork
linmiansheng
博客等级 码龄20年 507粉丝 111原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值