博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Glide 源码解析 之 内存缓存
阅读量:6695 次
发布时间:2019-06-25

本文共 4455 字,大约阅读时间需要 14 分钟。

注:为了突出重点,文中的源码有大量删节,有的用//..进行了标识,有的没有。

引子

图片加载

Engine#load()

public 
LoadStatus load(//..) { //.. // 一级内存缓存 EngineResource
active = loadFromActiveResources(key, isMemoryCacheable); if (active != null) { //.. return null; } // 二级内存内存 EngineResource
cached = loadFromCache(key, isMemoryCacheable); if (cached != null) { //.. return null; } //.. }复制代码

ActiveResources解析

获取 ActiveResource 缓存

Engine#loadFromActiveResources()

private final ActiveResources activeResources;    @Nullable  private EngineResource
loadFromActiveResources(Key key, boolean isMemoryCacheable) { //.. EngineResource
active = activeResources.get(key); //.. return active; }复制代码

ActiveResource

本质是一个HashMap,用WeekReference保存EngineResource,用作内存缓存。

final class ActiveResources {  final Map
activeEngineResources = new HashMap<>(); static final class ResourceWeakReference extends WeakReference
> { //.. } void activate(Key key, EngineResource
resource) { ResourceWeakReference toPut = new ResourceWeakReference(//..) ResourceWeakReference removed = activeEngineResources.put(key, toPut); //.. } void deactivate(Key key) { ResourceWeakReference removed = activeEngineResources.remove(key); if (removed != null) { removed.reset(); } } EngineResource
get(Key key) { ResourceWeakReference activeRef = activeEngineResources.get(key); //.. return active; }}复制代码

ActiveResources 缓存的添加和移除

从调用关系可以看到activate是在EngineJobCompleteloadFromcache时调用的,deactivate是在onResourceRelease时调用的。调用都是在Engine中,可见ActiveResources的维护都是有Engine维护的。

MemoryCache 解析

获取 MemoryCache 缓存

Engine#loadFromCache

private final MemoryCache cache;  private EngineResource
loadFromCache(Key key, boolean isMemoryCacheable) { //.. EngineResource
cached = getEngineResourceFromCache(key); //.. return cached; } private EngineResource
getEngineResourceFromCache(Key key) { Resource
cached = cache.remove(key); //.. return result; }复制代码

MemoryCache 的具体实现

MemoryCache 是一个接口, 默认的实现是LruResourceCache。 初始化逻辑: GlideBuilder#build

@NonNull  Glide build(@NonNull Context context) {    //..    if (memoryCache == null) {      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());    }        if (engine == null) {      engine =          new Engine(              memoryCache,            //..);    }    //..  }复制代码

LruResourceCache 的继承结构

LruResourceCache extends LruCache
> implements MemoryCache复制代码

MemoryCache 缓存的添加和移除

加入是在onResourceReleased,联系前面的源码只可以看到,在onResourceReleased中cache从ActiveResource中移出来,放到LruResourceCache中了。

移出是在getEngineResourceFromCache()中,从LruResourceCache移到ActiveResource中,刚好对应。

再来回顾一下Glide内存缓存的逻辑 onEngineJobComplete 图片被缓存到ActiveResources onResourceReleased 图片从ActiveResources移到LruResourceCache loadFromCache 图片从LruResourceCache移到ActiveResources

@Override  public void onEngineJobComplete(EngineJob
engineJob, Key key, EngineResource
resource) { //.. if (resource.isCacheable()) { activeResources.activate(key, resource); } } @Override public void onResourceReleased(Key cacheKey, EngineResource
resource) { activeResources.deactivate(cacheKey); //.. cache.put(cacheKey, resource); //.. } private EngineResource
loadFromCache(Key key, boolean isMemoryCacheable) { //.. EngineResource
cached = getEngineResourceFromCache(key); activeResources.activate(key, cached); return cached; } private EngineResource
getEngineResourceFromCache(Key key) { Resource
cached = cache.remove(key); //.. }复制代码

回顾Engine、ActivityResources、LruCacheResourceCache

从上面的分析可以看到,cache的加入和移除都是通过Engine的回调方法进行处理的,也就是说Engine监听图片加载过程中的各种事件,在事件发生的时候采取相应的行动维护缓存。Engine实现了3个interface,一个这对图片加载任务,一个针对ActiveResources,一个针对LruCacheResourceCache,结构非常清晰。

public class Engine implements EngineJobListener,    MemoryCache.ResourceRemovedListener,    EngineResource.ResourceListener{}    interface EngineJobListener {  void onEngineJobComplete(EngineJob
engineJob, Key key, EngineResource
resource); void onEngineJobCancelled(EngineJob
engineJob, Key key);}MemoryCacheinterface ResourceRemovedListener { void onResourceRemoved(@NonNull Resource
removed);}EngineResourceinterface ResourceListener { void onResourceReleased(Key key, EngineResource
resource);}复制代码

转载地址:http://wmvoo.baihongyu.com/

你可能感兴趣的文章
购物商城---页面缓存oscached
查看>>
java基础--理论2
查看>>
2017.12.14工程工艺问题
查看>>
2018.6.21 HOLTEK HT49R70A-1 Source Code analysis
查看>>
服务器设计笔记(4)-----客户端通信模块
查看>>
IntelliJ IDEA运行eclipse的web项目报错的问题
查看>>
url参数中有+、空格、=、%、&、#等特殊符号的问题解决
查看>>
Python文件指针与Python函数
查看>>
ORM系列之Entity FrameWork详解
查看>>
[转] java Class类
查看>>
编码转换
查看>>
MVC报错的坑
查看>>
那些争议最大的编程观点
查看>>
极简科普 1:什么是 VOIP
查看>>
11.10 (下午)开课二个月零六天(ajax验证用户名,ajax调数据库)
查看>>
PXC 避免加入集群时发生SST
查看>>
JS基础语法
查看>>
python 的一些tip 02
查看>>
int转字符串 stringstream
查看>>
pip升级时报错--- No module named 'pip._internal'
查看>>