浅谈Glide缓存key的问题
作者:Dynamic_2018 发布时间:2023-10-05 05:26:35
标签:Glide,缓存,key
最近项目里面有个地方是在前面用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了。
来源:https://www.jianshu.com/p/22b677d88b55
0
投稿
猜你喜欢
- java web返回中文乱码ajax返回中文乱码问题 在浏览器按F12查看数据包可以看到charset为 iso-8859-1,这是spri
- 先理解一下RFC(Romote Function Call)远程函数调用调用前提:1.要想通过C# 通过RFC调用SAP端,SAP端要存在R
- 一、在学习枚举之前,首先来听听枚举的优点。1、枚举能够使代码更加清晰,它允许使用描述性的名称表示整数值。2、枚举使代码更易于维护,有助于确保
- 在并发多线程的情况下,为了保证数据安全性,一般我们会对数据进行加锁,通常使用Synchronized或者ReentrantLock同步锁。S
- @Value值注入及配置文件组件扫描spring配置文件对应的是父容器,springMVC配置文件产生的是子容器,前者一般配置数据源,事务,
- 一、登录认证基于过滤器链Spring Security的登录验证流程核心就是过滤器链。当一个请求到达时按照过滤器链的顺序依次进行处理,通过所
- 导语:有些时候我们所需要查询的数据量比较大,但是jvm内存又是有限制的,数据量过大会导致内存溢出。这个时候就可以使用流式查询,数据一条条的返
- 有时候在配置中心有些参数是需要修改的,这时候如何不重启而达到实时生效的效果呢?添加依赖<dependencies>
- MyBatis 是一款常用的持久层框架,使得程序能够以调用方法的方式执行某个指定的SQL,将执行SQL的底层逻辑进行封装。多数与Spring
- Java的SPI机制实例详解SPI的全名为Service Provider Interface.普通开发人员可能不熟悉,因为这个是针对厂商或
- 顺序语句顺序顾名思义就是程序自上而下执行public class User { public static voi
- 前言两个数据结构:顺序表和链表数据结构是一门学科,和语言无关。数据 + 结构:一种描述和组织数据的方式。1. 顺序表顺序表是用一段物理地址连
- MapperScan添加动态配置(占位符)在对Mybatis自动扫描配置中,使用注解配置时,@MapperScan中的配置,通常配置如下:@
- 1.XxlJob简介官方网址:https://www.xuxueli.com/xxl-jobXXL-JOB是一个分布式任务调度平台,其核心设
- 概述在Compose中,图片组件主要有两种,分别是显示图标的Icon组件和显示图片的Image组件,当我们显示一系列的小图标的时候,我们可以
- 1.概述项目中经常会遇到一个应用需要访问多个数据源的情况,本文介绍在SpringBoot项目中利用SpringDataJpa技术如何支持多个
- 通过脚本命令行批量修改 Jenkins 任务最近,笔者所在团队的 Jenkins 所在的服务器经常报硬盘空间不足。经查发现很多任务没有设置“
- Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(
- Java io简介Java io系统的设计初衷,就是为了实现“文件、控制台、网络设备”这些io设置的通信。例如,对于一个文件,我们可以打开文
- 返回值转成JSONString的处理主要需求描述有些返回值中的null需要转换成“”或[],另外有些