位置: 编程技术 - 正文

从源码带看Volley的缓存机制(源码讲解)

编辑:rootadmin

推荐整理分享从源码带看Volley的缓存机制(源码讲解),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:看源码有什么用,看源码有什么用,源码教程,volley源码分析,源码讲解,volley源码分析,源码讲解,volley源码分析,内容如对您有帮助,希望把文章链接给更多的朋友!

转载请注明出处:

如果请求进来即调用Cache.Entry entry = mCache.get(request.getCacheKey()),那我们就看DiskBaseCache。get方法里做了什么:

从方法里可以看到,先从文件里获得字节数输入流,从中减去头部文件的字节数,最后把真正内容的data[]数据拿到再组装成一个Cache.Entry返回。不得不说,Volley这真是精打细算啊。

从上面的分析可见,cache在做一些基础判断时都会先用到缓存的头部数据,如果确定头部信息没问题了,再真正读写内容,原因是头部数据比较小,放在内存中也不占地方,但处理速度会快很多。而真正的数据内容,可能会比较大,处理的开销也大,只在真正需要的地方读写。

Volley对的处理

http的状态码的含义是:

如果服务器端的资源没有变化,则自动返回 HTTP (Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而 保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。

完整的过程如下:

客户端请求一个页面(A)。服务器返回页面A,并在给A加上一个Last-Modified/ETag。(Last-Modified为标记此文件在服务期端最后被修改的时间,ETag是这个请求的token)客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返 回响应和一个空的响应体。

介绍完,我们接下来来看看volley是怎么运用来重用缓存的。

Volley对于头部的解析

首先我们来看一下对于response.header的处理,在每一个request里,都必须继承 parseNetworkResponse(NetworkResponse response)方法,然后在里面用 HttpHeaderParser.parseCacheHeaders()解析类来解析头部数据,具体如下:

从源码带看Volley的缓存机制(源码讲解)

从上面代码可以看出缓存头部是根据 Cache-Control 和 Expires 首部,计算出缓存的过期时间(ttl),和缓存的新鲜度时间(softTtl,默认softTtl和ttl相同),如果有Cache-Control标签以它为准,没有就以Expires标签里的内容为准。

需要注意的是:Volley没有处理Last-Modify首部,而是处理存储了Date首部,并在后续的新鲜度验证时,使用Date来构建If-Modified-Since。 这与 Http 1.1 的语义有些违背。

Volley对于新鲜度和过期的验证

在使用缓存数据前,Volley会先对验证缓存数据是否过期,是否需要更新等属性,然后一一处理,代码在CacheDispatcher的run方法里:

上面代码都已经加了注释,相信不难理解,那我们继续看,网络请求是怎么判断是否需要更新缓存的,在BasicNetwork.performRequest()里:

从上面的注释可以看到,如果是返回就直接用缓存数据返回。那来看NetworkDispatcher的run()里:

现在流程比较清晰了,在有缓存的情况下,如果已经过期,但是返回,就复用缓存。如果不新鲜了,就先将缓存分发出去,然后再进行网络请求,看是否需要更新缓存。

不过眼尖的读者一定有个疑惑,在解析头部数据时,默认不是新鲜度和过期事件是一样的吗?那新鲜度不是一定运行不到吗?确实是这样,我也有这个疑惑,网上也找不到确切的资料来解释这一点。不过按照正常的逻辑,新鲜度时间一定比过期时间短,这样我们就可以根据实际需要更改Volley的源码。例如,我们可以直接把新鲜度的验证时间设为3分钟,而过期时间设为一天,代码如下:

然后使用的时候:

这样的话,在3分钟后就不新鲜,小时后就会过期。

图片的自定义内存缓存

我们使用ImageLoader时会传入一个ImageCache,它是个接口,里面定义了两个方法:

那他们是什么时候使用的呢,可以从开始请求数据ImageLoader.get()方法看起:

从上面的代码注释中已经能比较清晰的看出,每次调用ImageLoader.get()方法,会先从内存缓存里先看有没有数据,有就直接返回,没有就走正常的网络流程,先查看磁盘缓存,不存在或过期再去请求网络。图片比普通数据多一层缓存的原因也很简单,因为图片较大,读取和网络成本都大,能用缓存就用缓存,能省一点是一点。

标签: 源码讲解

本文链接地址:https://www.jiuchutong.com/biancheng/384338.html 转载请保留说明!

上一篇:焦点问题总结(焦点问题是什么)

下一篇:android 自定义滚动上下回弹scollView(android滚动布局)

  • 增值税专票开错了可以作废吗
  • 销售不动产税率9%还是5%
  • 小规模纳税人税额怎么做分录
  • 公司购买新车购置税是否可以抵扣呢
  • 未开票收入缴纳增值税怎么冲减补开发票
  • 发债评级机构 有哪些
  • 销售已计提完折旧的固定资产
  • 上市公司现金流充足说明什么
  • 小规模纳税人可以抵扣进项税吗
  • 与其他企业联营算投资吗
  • 进项发票当月不抵扣怎么入账
  • 应收账款转销怎么记账
  • 认证抵扣完的发票怎么处理
  • 委外技术服务费应归集哪个研发项目
  • 德邦物流增值税发票怎么开
  • 纳税人签字
  • 跨年度的应收账款少记了怎么办
  • 收到财付通打款认证冲减财务费用怎么做分录
  • 其他应付款在贷方,借方是什么科目
  • 股东借款利息计入利润表哪个科目
  • 计提减值的固定资产处置
  • 定额备用金的账务怎么做
  • 技术合同指什么
  • svchost进程很多怎么办
  • 所得税以前年度亏损
  • vue打开窗口
  • 慈善捐赠金额排行
  • 总公司拨给分公司款需要交税吗
  • WIN7系统如何共享打印机
  • 政府划入资产会计处理
  • 补缴以前年度公积金误入当年费怎么办
  • 个人所得税申报流程图
  • 累计盈余科目怎么填
  • 本季度企业所得税
  • 外管证预缴税费怎么算
  • 原始凭证必须来源于外部吗
  • 社保新参统委托代发银行
  • python输入三个数输出最小的
  • java泛型简单例子
  • 什么是银行对账,进行银行对账分为几步
  • 个人所得税申报流程图
  • 垃圾处理费计入办公费用吗
  • js array.fill
  • 计提工会经费是什么工资项目
  • 资产总额是营业收入吗
  • 小企业会计准则调整以前年度费用分录
  • 善意取得虚开增值税专用发票处理
  • 本月增加的无形资产本月摊销
  • 应付账款尾款怎么处理
  • 公司向法人借款有税务风险吗
  • 企业购买商场的资本金要求是多少
  • 零申报报表怎么填写
  • 发票免税怎么做账
  • 职工福利费的计提比例为职工工资总额扣除奖金后的
  • 金蝶的数量金额明细账是怎么做的
  • 注册工贸公司业务范围
  • 注册公司的流程及费用标准
  • 财务月末暂估成本是什么
  • 航天信息服务费280元如何申报
  • sql中的存储过程
  • asp 分页
  • 邻居家的wifi隐藏后如何连接
  • 苹果电脑 输入
  • 如何创建mac系统安装盘
  • linux常见信号
  • xp电脑繁体系统改简体
  • mac光盘无法退出怎么解决
  • Win10 Mobile 10586.36预览版怎么更新?
  • 博通网卡驱动win7
  • linux系统怎么弄
  • python计算两个数的最大公约数
  • android方法大全
  • android内存泄露 工具
  • node的express干什么用
  • 安卓模拟器比手机快吗
  • python并发原理
  • jquery中each()方法的作用及使用
  • wordpress 0day
  • 进项税跨月转出
  • 税务主管机关有哪些
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设