最近项目里面有个地方是在前面用glide加载图片后,后面再另外一个地方加载相同图片时没有复用glide的缓存,而是自己另外又重新缓存了一套。
查找后发现问题是glide缓存的key不一致的问题。
从key的生成可以看到和很多参数有关,逐一排查后,发现了width和height还有id不一样。这3个是项目外面传进来的。
EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(), loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(), transcoder, loadProvider.getSourceEncoder());
key的作用大概是通过下面三步里面去找数据
如果都为null,就会进入函数最后边的开线程去decode(相当于缓存没找到,准备重新加载数据吧)
EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable); DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation, transcoder, diskCacheProvider, diskCacheStrategy, priority); EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority); jobs.put(key, engineJob); engineJob.addCallback(cb); engineJob.start(runnable);
进入EngineRunnable的run方法看
resource = decode(); private Resource<?> decode() throws Exception { if (isDecodingFromCache()) { return decodeFromCache(); } else { return decodeFromSource(); } }
其中loadCache还是loadFromSource的条件
private boolean isDecodingFromCache() { return stage == Stage.CACHE; }
默认stage会进去,走到decodeFromCache(),由于cache里没有,返回null到run方法里面触发加载失败的回调
if (resource == null) { onLoadFailed(exception); } else { onLoadComplete(resource); }
在回调中重新提交一个runnable,改变stage,下一次run执行时,stage==source,就不会去loadCache,而是loadSource。(开线程加载大概流程感觉就像是默认先去缓存中找,没找到就重新加载)
private void onLoadFailed(Exception e) { if (isDecodingFromCache()) { stage = Stage.SOURCE; manager.submitForSource(this); } else { manager.onException(e); } }
loadSource会一路走到
private Resource<T> decodeFromSourceData(A data) throws IOException { final Resource<T> decoded; if (diskCacheStrategy.cacheSource()) { decoded = cacheAndDecodeSourceData(data); } else { long startTime = LogTime.getLogTime(); decoded = loadProvider.getSourceDecoder().decode(data, width, height); if (Log.isLoggable(TAG, Log.VERBOSE)) { logWithTimeAndKey("Decoded from source", startTime); } }
这里回调的decode就是项目中自己设置的sourceDecoder
项目内的代码象征性的打码:
之前id和宽高传的不一样,导致key不一样,然后Glide加载的时候通过key找不到缓存,最后就又回调到项目里面的decode那里来了。
改完后,第一次decode完后,后面用缓存就不会再进入decode了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍浅谈Django的缓存机制,包括了浅谈Django的缓存机制的使用技巧和注意事项,需要的朋友参考一下 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之
本文向大家介绍浅谈HTTP 缓存的那些事儿,包括了浅谈HTTP 缓存的那些事儿的使用技巧和注意事项,需要的朋友参考一下 前言 HTTP 缓存机制作为 Web 应用性能优化的重要手段,对于从事 Web 开发的同学们来说,应该是知识体系的基础环节,也是想要成为前端架构的必备技能。 缓存的作用 我们为什么使用缓存,是因为缓存可以给我们的 Web 项目带来以下好处,以提高性能和用户体验。 加快了浏览器加载
本文向大家介绍浅谈iOS UIWebView对H5的缓存功能,包括了浅谈iOS UIWebView对H5的缓存功能的使用技巧和注意事项,需要的朋友参考一下 这两天在搞与H5交互的事,之前做的都是加载的静态的web页面,交互调试起来很快,这次搞的是js写的前端页面,跳转什么的都是动态的,然后就不响应了,搞了半天原来是缓存的问题,这里简单介绍一下,一般请求会使用下面的方法: 该方法的描述如下: Cre
本文向大家介绍浅谈Webpack 持久化缓存实践,包括了浅谈Webpack 持久化缓存实践的使用技巧和注意事项,需要的朋友参考一下 前言 最近在看 webpack 如何做持久化缓存的内容,发现其中还是有一些坑点的,正好有时间就将它们整理总结一下,读完本文你大致能够明白: 什么是持久化缓存,为什么做持久化缓存? webpack 如何做持久化缓存? webpack 做缓存的一些注意点。 持久化缓存 首
本文向大家介绍浅谈Ajax请求与浏览器缓存,包括了浅谈Ajax请求与浏览器缓存的使用技巧和注意事项,需要的朋友参考一下 在现代Web应用程序中,前端代码充斥着大量的Ajax请求,如果对于Ajax请求可以使用浏览器缓存,那么可以显著地减少网络请求,提高程序响应速度。 1. Ajax Request 使用jQuery框架可以很方便的进行Ajax请求,示例代码如下: 非常简单,注意其中的第4行代码:ca
本文向大家介绍浅谈Redis的key和value大小限制,包括了浅谈Redis的key和value大小限制的使用技巧和注意事项,需要的朋友参考一下 今天研究了下将java bean序列化到redis中存储起来,突然脑袋灵光一闪,对象大小会不会超过redis限制?不管怎么着,还是搞清楚一下比较好,所以就去问了下百度,果然没多少人关心这个问题,没找到比较合适的答案,所以决定还是去官网找吧。 找到两句比