@946898963
2018-05-18T11:26:00.000000Z
字数 3308
阅读 1025
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 eventually
throw 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 eventually
throw 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源码解读