Glide Disk Cache 设计


缓存策略

DiskCacheStrategy类,五种缓存策略。
1,ALL
2,NONE
3,DATA
4,RESOURCE
5,AUTOMATIC,默认

DiskCache接口

内部工厂Factory

类图

Disk Cache

获取一个DiskLruCacheWrapper,存入缓存。cacheData方法,最后,会创建一个DataCacheGenerator对象,在startNext后面会判断该对象不空,执行它的startNext()方法,将从Disk缓存中获取一次,成功返回。

根据key获取File

DiskCache的实现:
1,DiskCacheAdapter空实现

2,DiskLruCacheWrapper
持久化缓存
DiskLruCacheFactory工厂实现,创建DiskLruCacheWrapper

DiskLruCacheFactory 子类,
ExternalPreferredCacheDiskCacheFactory
InternalCacheDiskCacheFactory

区别是 CacheDirectoryGetter 不同,内部存储和外部存储。
GlideBuilder默认使用 InternalCacheDiskCacheFactory

ExternalCacheDiskCacheFactory 废弃。

可配置 DiskCacheFactory 工厂。
ExternalPreferredCacheDiskCacheFactory 工厂,优先内部存储,必须在 cache 目录下存在的文件夹才可。或者传入 diskCacheName 是"",使用 cache 目录。

File internalCacheDirectory = getInternalCacheDirectory();

// Already used internal cache, so keep using that one,
// thus avoiding using both external and internal with transient errors.
if ((null != internalCacheDirectory) && internalCacheDirectory.exists()) {
    return internalCacheDirectory;
 }

不满足再决定使用外部存储。

DiskLruCache缓存
缓存根目录:/storage/emulated/0/Android/data/com.glide.app/cache/Images
日志:/storage/emulated/0/Android/data/com.glide.app/cache/Images/journal
内部目录
static final String JOURNAL_FILE = "journal";
static final String JOURNAL_FILE_TEMP = "journal.tmp";
static final String JOURNAL_FILE_BACKUP = "journal.bkp";

在DiskLruCacheWrapper中,真正通过Key获取file的类

DiskLruCache,journalFile

readJournal()读取journalFile文件。
journalFile文件存储本地缓存key,一行一行的读,有标志 CLEAN,DIRTY,REMOVE,READ

和Entry对象关联,key对应一个Entry,从日志到Entry的map

journal 文件,记录每一个 key 状态轨迹,Dirty、Clean、Read 状态

libcore.io.DiskLruCache
1
1
1

DIRTY 0c39751c644c22f9cd0474c7b6b641426b980a89d29f3fa4200c97ec373decba
CLEAN 0c39751c644c22f9cd0474c7b6b641426b980a89d29f3fa4200c97ec373decba 2471
READ 0c39751c644c22f9cd0474c7b6b641426b980a89d29f3fa4200c97ec373decba
DIRTY 30e8fb2ca2f9d90c31abe7fec2faba7442090bded5822fd475f75af6cfecb646
CLEAN 30e8fb2ca2f9d90c31abe7fec2faba7442090bded5822fd475f75af6cfecb646 1492
READ 30e8fb2ca2f9d90c31abe7fec2faba7442090bded5822fd475f75af6cfecb646
DIRTY 1b463288c292fcf5ccdb8a7b62e5212aab655e75e28ccffc05a80cfb9f0dfde7
CLEAN 1b463288c292fcf5ccdb8a7b62e5212aab655e75e28ccffc05a80cfb9f0dfde7 32909
READ 1b463288c292fcf5ccdb8a7b62e5212aab655e75e28ccffc05a80cfb9f0dfde7
DIRTY 97ea0a132656fcd8d2ff708f53873acb9302963cb96096660163e4fbd6b6e34b
CLEAN 97ea0a132656fcd8d2ff708f53873acb9302963cb96096660163e4fbd6b6e34b 40819
READ 97ea0a132656fcd8d2ff708f53873acb9302963cb96096660163e4fbd6b6e34b

DiskCache 使用

DiskCache 接口,定义了存储,删除,获取File的方法,与key相关。
DiskCache内部Factory接口,负责创建DiskCache对象,Factory定义了可使用的磁盘大小

/** 250 MB of cache. */
int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;
String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";

DiskLruCacheFactory实现DiskCache.Factory,创建DiskCache的build方法。

@Override
public DiskCache build() {
    File cacheDir = cacheDirectoryGetter.getCacheDirectory();
    if (cacheDir == null) {
      return null;
    }
    if (!cacheDir.mkdirs() && (!cacheDir.exists() || 
                    !cacheDir.isDirectory())) {
      return null;
    }
    return DiskLruCacheWrapper.get(cacheDir, diskCacheSize);
}

DiskLruCacheWrapper实现DiskCache接口。get方法创建并返回静态内部单例对象DiskLruCacheWrapper。
cacheDir 缓存目录根据 CacheDirectoryGetter 获取,可使用缓存就是在Factory定义的大小。


任重而道远

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。