Android开发中,使用 Glide 加载图片资源是一个很常见的方案。但是最近我遇到了一个十分诡异的问题:
使用 Glide 加载本地
R.mipmap 资源时,加载的图片竟然不是我传入的资源 ID,而是上一次加载的另一张图片
通过排查和实验证实,该问题的根本原因在于:
Glide 对本地资源的缓存机制,结合
mipmap 类型资源的特殊性,导致了图片错乱加载。
本文将记录这个问题的详细分析过程、验证方法及最终解决方案。
我定义了一个枚举类
ImageTypeEnum 来管理多种类型图标及其背景图资源:
enum class ImageTypeEnum(val id: Int, val iconRes: Int, val backgroundRes: Int) {
CUSTOM(0, R.mipmap.ic_custom, -1),
TYPE_A(1, R.mipmap.ic_type_a, R.mipmap.bg_type_a),
TYPE_B(2, R.mipmap.ic_type_b, R.mipmap.bg_type_b),
TYPE_C(3, R.mipmap.ic_type_c, R.mipmap.bg_type_c),
TYPE_D(4, R.mipmap.ic_type_d, R.mipmap.bg_type_d)
}
在 UI 中我希望根据当前项动态设置背景图,使用了如下 Glide 加载方式:
Glide.with(this)
.load(currentItem.backgroundRes)
.into(object : CustomTarget<Drawable>() {
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
binding.containerLayout.background = resource
}
override fun onLoadCleared(placeholder: Drawable?) {}
})
当我切换到
TYPE_B 项时,原本应显示的
bg_type_b 背景图,却意外地加载成了
bg_type_a 的图片。
而当我将代码改为使用系统原生方式设置背景图时,一切又正常了:
binding.containerLayout.setBackgroundResource(currentItem.backgroundRes)
说明资源 ID 本身是正确的,问题只出现在 Glide 加载流程中。
通过日志打印
currentItem.backgroundRes,确认其确实是
R.mipmap.bg_type_b,与实际期望值一致。
资源 ID 本身没问题。
Glide 默认会启用内存缓存和磁盘缓存,考虑是否因为资源 ID 相近或内容类似导致缓存误用。
我修改 Glide 加载方式以禁用缓存:
Glide.with(this)
.load(currentItem.backgroundRes)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(object : CustomTarget<Drawable>() {
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
binding.containerLayout.background = resource
}
override fun onLoadCleared(placeholder: Drawable?) {}
})
结果: 问题消失了。背景图加载正确,说明问题确实来自 Glide 缓存逻辑。
我把所有图片资源放在了
res/mipmap 目录,而非
drawable。但
mipmap 主要用于应用图标,它在构建过程中有独特处理方式,不推荐用作界面图像资源。
Glide 加载
mipmap 资源时可能无法完全区分 ID 或文件路径,从而导致缓存错乱。
基于以上结论,最终做了如下优化:
将资源文件移至
res/drawable;
不再使用 Glide 加载本地背景图;
使用更安全的原生设置方式:
binding.containerLayout.setBackgroundResource(currentItem.backgroundRes)
这个问题其实并不复杂,但涉及多个原因(资源目录、缓存机制、工具使用边界)。也实实在在卡住了我多个小时排查问题
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69917874/viewspace-3085786/ ,如需转载,请注明出处,否则将追究法律责任。