[关闭]
@946898963 2018-05-18T11:26:00.000000Z 字数 3308 阅读 1025

Volley-DiskBasedCache的内部类CacheHeader的源码分析

Android控件跟框架 Android源码分析


DiskBasedCache中定义了一个CacheHeader内部类,表示缓存信息的摘要,存储在缓存文件的头部,网络请求的缓存写入与读取都是通过CacheHeadler类来操作的。与Cache接口的内部类Cache.Entry相似。

CacheHeader的源码:

  1. static class CacheHeader {
  2. /**缓存文件的大小 */
  3. public long size;
  4. /**缓存文件的key,也就是url */
  5. public String key;
  6. /** 用于缓存新鲜度验证的 ETag */
  7. public String etag;
  8. /** 缓存产生的时间 */
  9. public long serverDate;
  10. /** 缓存文件在服务器端最后的修改时间 */
  11. public long lastModified;
  12. /** 缓存过期时间*/
  13. public long ttl;
  14. /** 缓存的新鲜度时间 */
  15. public long softTtl;
  16. /** 缓存对应的首部信息 */
  17. public Map<String, String> responseHeaders;
  18. private CacheHeader() { }
  19. public CacheHeader(String key, Entry entry) {
  20. this.key = key;
  21. this.size = entry.data.length;
  22. this.etag = entry.etag;
  23. this.serverDate = entry.serverDate;
  24. this.lastModified = entry.lastModified;
  25. this.ttl = entry.ttl;
  26. this.softTtl = entry.softTtl;
  27. this.responseHeaders = entry.responseHeaders;
  28. }
  29. public static CacheHeader readHeader(InputStream is) throws IOException {
  30. CacheHeader entry = new CacheHeader();
  31. int magic = readInt(is);
  32. if (magic != CACHE_MAGIC) {
  33. // don't bother deleting, it'll get pruned eventually
  34. throw new IOException();
  35. }
  36. entry.key = readString(is);
  37. entry.etag = readString(is);
  38. if (entry.etag.equals("")) {
  39. entry.etag = null;
  40. }
  41. entry.serverDate = readLong(is);
  42. entry.lastModified = readLong(is);
  43. entry.ttl = readLong(is);
  44. entry.softTtl = readLong(is);
  45. entry.responseHeaders = readStringStringMap(is);
  46. return entry;
  47. }
  48. public Entry toCacheEntry(byte[] data) {
  49. Entry e = new Entry();
  50. e.data = data;
  51. e.etag = etag;
  52. e.serverDate = serverDate;
  53. e.lastModified = lastModified;
  54. e.ttl = ttl;
  55. e.softTtl = softTtl;
  56. e.responseHeaders = responseHeaders;
  57. return e;
  58. }
  59. public boolean writeHeader(OutputStream os) {
  60. try {
  61. writeInt(os, CACHE_MAGIC);
  62. writeString(os, key);
  63. writeString(os, etag == null ? "" : etag);
  64. writeLong(os, serverDate);
  65. writeLong(os, lastModified);
  66. writeLong(os, ttl);
  67. writeLong(os, softTtl);
  68. writeStringStringMap(responseHeaders, os);
  69. os.flush();
  70. return true;
  71. } catch (IOException e) {
  72. VolleyLog.d("%s", e.toString());
  73. return false;
  74. }
  75. }
  76. }

readHeader(InputStream is)读头信息:

  1. public static CacheHeader readHeader(InputStream is) throws IOException {
  2. CacheHeader entry = new CacheHeader();
  3. int magic = readInt(is);
  4. if (magic != CACHE_MAGIC) {
  5. // don't bother deleting, it'll get pruned eventually
  6. throw new IOException();
  7. }
  8. entry.key = readString(is);
  9. entry.etag = readString(is);
  10. if (entry.etag.equals("")) {
  11. entry.etag = null;
  12. }
  13. entry.serverDate = readLong(is);
  14. entry.lastModified = readLong(is);
  15. entry.ttl = readLong(is);
  16. entry.softTtl = readLong(is);
  17. entry.responseHeaders = readStringStringMap(is);
  18. return entry;
  19. }

在方法体的第三行,验证输入流对应的缓存文件的合法性。如果读出的magic不等于写入的magic,终止读写,如果合法,从缓存文件中读出结构数据,组成对象返回。

writeHeader(OutputStream os)与上面方法相反,这里将maic和一些属性信息写入到缓存文件。注意写文件也是按照结构来写。

  1. public boolean writeHeader(OutputStream os) {
  2. try {
  3. writeInt(os, CACHE_MAGIC);
  4. writeString(os, key);
  5. writeString(os, etag == null ? "" : etag);
  6. writeLong(os, serverDate);
  7. writeLong(os, lastModified);
  8. writeLong(os, ttl);
  9. writeLong(os, softTtl);
  10. writeStringStringMap(responseHeaders, os);
  11. os.flush();
  12. return true;
  13. } catch (IOException e) {
  14. VolleyLog.d("%s", e.toString());
  15. return false;
  16. }
  17. }

toCacheEntry(byte[] data)方法,此方法用于将头信息和数据信息封装成Entry(Cache的单位数据)返回,代码很简单。

  1. public Entry toCacheEntry(byte[] data) {
  2. Entry e = new Entry();
  3. e.data = data;
  4. e.etag = etag;
  5. e.serverDate = serverDate;
  6. e.lastModified = lastModified;
  7. e.ttl = ttl;
  8. e.softTtl = softTtl;
  9. e.responseHeaders = responseHeaders;
  10. return e;
  11. }

readInt 和writeInt
readLong和 writeLong
readString和writeString
readStringStringMap和writeStringStringMap
这些方法是DiskBasedCache中定义的方法,主要用于头信息读写有结构的数据,其中夹杂着一些自定义的位运算,这部分的源码没看懂。

Volley的cache之硬盘缓存--DiskBasedCache(作者的其他博文也值得学习)
Volley源码解读

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注