Glide的缓存包含内存缓存 和磁盘缓存

内存缓存

内存缓存部分可以细分为活动缓存ActiveResources和内存缓存MemoryCache

活动缓存:使用了弱引用方式,针对正在使用的图片,不使用的图片即释放回内存缓存

内存缓存:使用了lru

读取部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
基于glide4.11.0版本
Engine#loadFromMemory()

private EngineResource<?> loadFromMemory(
EngineKey key, boolean isMemoryCacheable, long startTime) {
if (!isMemoryCacheable) {
return null;
}

///1.从活动缓存中获取图片
EngineResource<?> active = loadFromActiveResources(key);
if (active != null) {
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return active;
}
///2.从缓存中获取图片
EngineResource<?> cached = loadFromCache(key);
if (cached != null) {
if (VERBOSE_IS_LOGGABLE) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return cached;
}

return null;
}

上面代码可以看到关于缓存的读取顺序

1.先从活动缓存中读取

2.再从内存缓存中读取

写入部分

1.活动缓存写入

a.从网络或磁盘加载图片数据之后

1
2
3
4
5
6
7
8
9
10
11
Engine.class
public synchronized void onEngineJobComplete(
EngineJob<?> engineJob, Key key, EngineResource<?> resource) {

if (resource != null && resource.isMemoryCacheable()) {
//a.写入
activeResources.activate(key, resource);
}

jobs.removeIfCurrent(key, engineJob);
}

b.从内存缓存中获取后

1
2
3
4
5
6
7
8
9
10
11
Engine.class
private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {

EngineResource<?> cached = getEngineResourceFromCache(key);
if (cached != null) {
cached.acquire();
//b.写入
activeResources.activate(key, cached);
}
return cached;
}

内存缓存写入

1
2
3
4
5
6
7
8
9
public void onResourceReleased(Key cacheKey, EngineResource<?> resource) {

activeResources.deactivate(cacheKey);
if (resource.isMemoryCacheable()) {
cache.put(cacheKey, resource);
} else {
resourceRecycler.recycle(resource, /*forceNextFrame=*/ false);
}
}

活动缓存中activeResource.deactivate后添加到内存缓存MemoryCache cache中

磁盘缓存

磁盘缓存使用方式

读取部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
DataCacheGenerator.class
public boolean startNext() {
while (modelLoaders == null || !hasNextModelLoader()) {
sourceIdIndex++;
if (sourceIdIndex >= cacheKeys.size()) {
return false;
}
Key sourceId = cacheKeys.get(sourceIdIndex);

Key originalKey = new DataCacheKey(sourceId, helper.getSignature());

///读取diskLurCache
cacheFile = helper.getDiskCache().get(originalKey);
if (cacheFile != null) {
this.sourceKey = sourceId;
modelLoaders = helper.getModelLoaders(cacheFile);
modelLoaderIndex = 0;
}
}
...
return started;
}

写入部分

分析各种缓存使用的场景

第一次加载

多次加载

应用退到后台再置前台

杀死进程再唤醒

(待补充)