@946898963
2018-05-18T03:26:00.000000Z
字数 3308
阅读 1305
Android控件跟框架 Android源码分析
DiskBasedCache中定义了一个CacheHeader内部类,表示缓存信息的摘要,存储在缓存文件的头部,网络请求的缓存写入与读取都是通过CacheHeadler类来操作的。与Cache接口的内部类Cache.Entry相似。
CacheHeader的源码:
static class CacheHeader {/**缓存文件的大小 */public long size;/**缓存文件的key,也就是url */public String key;/** 用于缓存新鲜度验证的 ETag */public String etag;/** 缓存产生的时间 */public long serverDate;/** 缓存文件在服务器端最后的修改时间 */public long lastModified;/** 缓存过期时间*/public long ttl;/** 缓存的新鲜度时间 */public long softTtl;/** 缓存对应的首部信息 */public Map<String, String> responseHeaders;private CacheHeader() { }public CacheHeader(String key, Entry entry) {this.key = key;this.size = entry.data.length;this.etag = entry.etag;this.serverDate = entry.serverDate;this.lastModified = entry.lastModified;this.ttl = entry.ttl;this.softTtl = entry.softTtl;this.responseHeaders = entry.responseHeaders;}public static CacheHeader readHeader(InputStream is) throws IOException {CacheHeader entry = new CacheHeader();int magic = readInt(is);if (magic != CACHE_MAGIC) {// don't bother deleting, it'll get pruned eventuallythrow new IOException();}entry.key = readString(is);entry.etag = readString(is);if (entry.etag.equals("")) {entry.etag = null;}entry.serverDate = readLong(is);entry.lastModified = readLong(is);entry.ttl = readLong(is);entry.softTtl = readLong(is);entry.responseHeaders = readStringStringMap(is);return entry;}public Entry toCacheEntry(byte[] data) {Entry e = new Entry();e.data = data;e.etag = etag;e.serverDate = serverDate;e.lastModified = lastModified;e.ttl = ttl;e.softTtl = softTtl;e.responseHeaders = responseHeaders;return e;}public boolean writeHeader(OutputStream os) {try {writeInt(os, CACHE_MAGIC);writeString(os, key);writeString(os, etag == null ? "" : etag);writeLong(os, serverDate);writeLong(os, lastModified);writeLong(os, ttl);writeLong(os, softTtl);writeStringStringMap(responseHeaders, os);os.flush();return true;} catch (IOException e) {VolleyLog.d("%s", e.toString());return false;}}}
readHeader(InputStream is)读头信息:
public static CacheHeader readHeader(InputStream is) throws IOException {CacheHeader entry = new CacheHeader();int magic = readInt(is);if (magic != CACHE_MAGIC) {// don't bother deleting, it'll get pruned eventuallythrow new IOException();}entry.key = readString(is);entry.etag = readString(is);if (entry.etag.equals("")) {entry.etag = null;}entry.serverDate = readLong(is);entry.lastModified = readLong(is);entry.ttl = readLong(is);entry.softTtl = readLong(is);entry.responseHeaders = readStringStringMap(is);return entry;}
在方法体的第三行,验证输入流对应的缓存文件的合法性。如果读出的magic不等于写入的magic,终止读写,如果合法,从缓存文件中读出结构数据,组成对象返回。
writeHeader(OutputStream os)与上面方法相反,这里将maic和一些属性信息写入到缓存文件。注意写文件也是按照结构来写。
public boolean writeHeader(OutputStream os) {try {writeInt(os, CACHE_MAGIC);writeString(os, key);writeString(os, etag == null ? "" : etag);writeLong(os, serverDate);writeLong(os, lastModified);writeLong(os, ttl);writeLong(os, softTtl);writeStringStringMap(responseHeaders, os);os.flush();return true;} catch (IOException e) {VolleyLog.d("%s", e.toString());return false;}}
toCacheEntry(byte[] data)方法,此方法用于将头信息和数据信息封装成Entry(Cache的单位数据)返回,代码很简单。
public Entry toCacheEntry(byte[] data) {Entry e = new Entry();e.data = data;e.etag = etag;e.serverDate = serverDate;e.lastModified = lastModified;e.ttl = ttl;e.softTtl = softTtl;e.responseHeaders = responseHeaders;return e;}
readInt 和writeInt
readLong和 writeLong
readString和writeString
readStringStringMap和writeStringStringMap
这些方法是DiskBasedCache中定义的方法,主要用于头信息读写有结构的数据,其中夹杂着一些自定义的位运算,这部分的源码没看懂。
Volley的cache之硬盘缓存--DiskBasedCache(作者的其他博文也值得学习)
Volley源码解读