求解惑

我很納悶,爲什麼我用Volley請求StringRequest,存了緩存文件,但是在沒有網絡的情況下卻不能讀出。

首先,我門通過 StringRequest
@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
這個方法調用由我們自己訂製的方法 onResponse(),我門在onResponse()中寫入我們對於獲得網絡的數據的處理

@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}
}

這個方法用於將網絡返回的抽象的數據類型轉化成我們需要的數據類型,這裏是String類型。

可以看到,無網絡狀態下,文本輸出爲null
而toast的值爲之前的請求:
byte[] data=mySingleton.getRequestQueue().getCache().get(sRequest.getCacheKey()).data;
Toast.makeText(this, new String(data), Toast.LENGTH_LONG).show();
由此可知,在RequestQueue的Cache中有我們所需的緩存。那麼爲什麼我們不能通過文筆顯示呢?
當我們使用byte[] data=sRequest.getCacheEntry().data;時,報出空指針異常,所以sRequest.getCacheEntry()爲空。
所以,在源碼的CacheDispatcher中:
// Attempt to retrieve this item from cache.
Cache.Entry entry = mCache.get(request.getCacheKey());
if (entry == null) {
request.addMarker("cache-miss");
// Cache miss; send off to the network dispatcher.
mNetworkQueue.put(request);
continue;
}

// If it is completely expired, just send it to the network.
if (entry.isExpired()) {
request.addMarker("cache-hit-expired");
request.setCacheEntry(entry);
mNetworkQueue.put(request);
continue;
}
entry不爲空。
Toast.makeText(this, ""+entry.isExpired(), Toast.LENGTH_LONG).show();
true
entry爲失效。
Toast.makeText(this, ""+sRequest.getCacheEntry(), Toast.LENGTH_LONG).show();
null
entry爲空
明明我們可以從entry裏面獲得值的,爲什麼輸出是null?
通過這篇文章的

http://www.cnblogs.com/angeldevil/p/3735051.html

在Request类中有一个方法叫parseNetworkResponse,Request的子类会覆写这个方法解析网络请求的结果,在这个方法中会调用

return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
返回Response<T>,并通过HttpHeaderParse.parseCacheHeaders解析Cache.Entity,即生成缓存对象,在parseaCheHeaders中会根据网络请求结果中的Header中的Expires、Cache-Control等信息判断是否需要缓存,如果不需要就返回null不缓存。

当对请求做了缓存后,没网的情况下也可以得到数据。
我們可以看看位於Request子類的parseNetworkResponse()方法,以StringRequest爲例:

@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}

於是,我們轉換到Response,success()方法:
public static <T> Response<T> success(T result, Cache.Entry cacheEntry) {
return new Response<T>(result, cacheEntry);
}
我們知道它是返回含cacheEntry的方法。那麼HttpHeaderParser.parseCacheHeaders(response)是幹什麼的呢?
因爲代碼過長,直接看這一句:
if (token.equals("no-cache") || token.equals("no-store")) {
return null;
} else if (token.startsWith("max-age=")) {
try {
maxAge = Long.parseLong(token.substring(8));
} catch (Exception e) {
}
我們通過chrome可以看到:根據header來指定緩存的時間。

我傳入的網址cache-control爲no-cache,返回的是null.
但此處是在網路請求過後才會出現的,於是,我們需要進DiskBasedCache和網絡請求看看。
request.shouldCache默認爲true.
if (request.shouldCache() && response.cacheEntry != null) {
mCache.put(request.getCacheKey(), response.cacheEntry);
request.addMarker("network-cache-written");
}
由此可見NetworkDispatcher只是進行網絡請求,並把它的結果傳給下一級,順便,把由各子類封裝的parseNetworkResponse的Response數據的cacheEntry數據存在文件中~
看了這一串,應該還記得我們是爲什麼說這麼多吧?說實話,我往回翻了好多次。
因爲我們在數據中已經存了這個文件,所以直接用cache可以獲得entry,因爲Request的默認爲: private Cache.Entry mCacheEntry = null;

我也是醉了。現在糾結
byte[] data=mySingleton.getRequestQueue().getCache().get(sRequest.getCacheKey()).data;
有值。

// Attempt to retrieve this item from cache.
Cache.Entry entry = mCache.get(request.getCacheKey());
if (entry == null) {
request.addMarker("cache-miss");
// Cache miss; send off to the network dispatcher.
mNetworkQueue.put(request);
continue;
}

// If it is completely expired, just send it to the network.
if (entry.isExpired()) {
request.addMarker("cache-hit-expired");
request.setCacheEntry(entry);

sRequest.getCacheEntry()爲空,問entry爲空還是isExpired.現在 isExpired爲true爲真,按照邏輯,應該在第一個if條件句,entry爲null,但mySingleton.getRequestQueue().getCache().get(sRequest.getCacheKey()).data;有輸出值??

时间: 2024-08-10 07:49:37

求解惑的相关文章

数据库中批量导入数据,有两列的值需要从其他表中查出来,我现在没有思路,求解惑

我现在批量往数据库里导正式数据(sql insert),但是数据中有三列分别是岗位,办事处,大区,给的数据中只给了岗位的值,办事处的值可以通过岗位值在岗位表查到,大区的值可以通过办事处的值在办事处表里查到.现在我已经把其他数据都导进去了,只剩办事处和大区没有值,我该如何批量更新这两列的值啊 导入的数据的表: 岗位表: 办事处表: 本人sql不是很好,希望sql大神能给出来解惑一下,拜谢~ 数据库中批量导入数据,有两列的值需要从其他表中查出来,我现在没有思路,求解惑 >> mysql 这个答案描

【求助】因为相同类型的其他实体已具有相同的主键值。在使用 &quot;Attach&quot; 方法或者将实体的状态设置为 &quot;Unchanged&quot; 或 &quot;Modified&quot; 。。。

因为相同类型的其他实体已具有相同的主键值.在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为.这可能是因为某些实体是新的并且尚未接收数据库生成的键值.在此情况下,使用 "Add" 方法或者 "Added" 实体状态跟踪该图形,然后将非新实体的状态相应设置为 "Unchanged"

Java线程范围内的共享数据(2)

实际上那么Map也就是模拟的ThreadLocal 每一个线程调用全局的ThreadLocal对象的set方法,就相当于往其内部的map记录新的键值对,键是Thread.current,值是data 线程结束后,可以选择调用ThreadLocal的clear()方法,释放内存,当某一个线程死掉后,可以用remove()移走 相关的变量,但是问题是,如何监听得知某个线程即将死亡? ThreadDeadRequest事件,只说了一点,太含糊,求解惑? import java.util.Random;

OSChina 周六乱弹 —— 阅兵女兵方队无码图

阅兵式都过去两天了,要说阅兵上最遗憾的是什么?恐怕很多小伙伴都会说是没有女兵的特写镜头吧 现在小小编就满足你们 我特别喜欢这一张 Via:精神漫游者_亦然V 看来不仅帅哥都去当兵了,连美女也当兵去了 其实我们身边也有这样的姑娘 @蓝血的阿健:IT行业要做到50万年薪,一般需要什么样的能力呢?跟编程能力还有关系吗?求解惑 你们做市场的同事是男是女呢? 有的女同志加你微信,明显对你图谋不轨 @撒拉嘿:要你们,会怎么做 看她这么诚恳,要不你就从了她吧 听说怕老婆是中华民族传统美德,是吗? @英强:"老

jdbc桥连接过程解析

读多少源码,便知自己有多无知! 想温习一下桥链接模式,然后觉得自己已然吃透了,因为自己写的博客,觉得还是应该更具体一些. 类似于这样的结构: 个人理解: 结构型模式 - 桥连接模式 概述: Bridge模式的应用场景 结构图: 桥接模式的优缺点 桥连接模式的应用实例 代码(其实读UML图要比代码还要一目了然) 参考/转自 便是一目了然了,觉得应该找个在Java中桥连接模式的实际应用,于是就找到了Jdbc连接. 于是,困惑的旅程开始了....... //加载及注册JDBC驱动程序 Class.fo

js单条新闻向上滚动

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title></title> <style> a{display:block;font-size:15px;line-height:18px;tex

js实现新闻滚动-单行滚动或者多行滚动

注明:都是转载. 先说单行滚动: --------直接复制以下代码即可试验 转载http://www.3lian.com/edu/2011/06-30/4986.html----------- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xm

领导异地高升,晚上大伙践行,饭桌一席话,胜读十年书,八年公司经历,肺腑之言,获益非浅

领导异地高升,晚上大伙践行,饭桌一席话,胜读十年书,八年公司经历,肺腑之言,获益非浅.怕自己记性不好,过事就忘,总结出以下几点: 1.做好自己,凡事努力而为,机会总是有的,东边不亮西边亮,今年不亮明年亮. 2.不要担心领导阻力,三年轮岗制,影响再怎么终有限: 3.推动力要强,只要为了问题解决,哪怕是协调多方领导,终会获得认可: 4.勤沟通,上对领导求解惑,下对员工点谜经,兄弟部门游协助: 5.认清自己,找好定位,专业路线也不错,一定要加强专业知识积累: 6. 严格要求自己,制造与传播正能量,对事

zedboard各种相关资料整理中

目录 知识篇.. 1 Zedboard实现Linux. 1 中断.. 1 裸机中断实验硬件配置.. 2 oled驱动.. 2 约束.. 2 [Vivado使用误区与进阶]XDC约束技巧-- I/O篇.. 2 教程篇.. 2 何宾网络课堂.. 2 高亚军-vivado入门与提高.. 2 资源篇.. 2 Xilinx官网用户指南地址.. 2 相关博客.. 3 转自其他博客.. 3 知识篇 Zedboard实现Linux http://blog.chinaunix.net/xmlrpc.php?r=b