Glide FAQ

本文深入探讨Glide的图片加载机制,解析复用和请求取消的原理,内存缓存策略,解决ImageView宽高wrap_content导致的缓存失效,动画性能优化,以及常见问题如RecyclerView卡顿和加载失败的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

view的复用和请求的取消是如何做到的?

into()
clear()

通过这两个方法均可以,into其实也就是调用了clear,通俗的来说,同一个ImageView(包括复用的),如果两个请求,那么后一个会生效,前一个会被取消,在RecyclerView的场景中,图片复用的bug将不会出现,原因是复用的view每次Into时Glide都会帮我们调用clear方法来取消之前的任务(这是通俗的说法,从源码的角度来说,它做了取消之前的请求释放资源改变状态等操作),

内存缓存同时使用弱引用+Lru,为什么这么做?

这个问题困扰了我很久,但我自己还没有找到能说服自己的答案,网上很多种说法,我给总结为两类,一种说法是弱引用数组是为了防止Lru回收掉正在显示的图片,一种说法是弱引用并不能延迟回收的速度,毕竟随时都可能发生GC,弱引用是为了防止LRU回收不了正在显示的图片造成内存泄漏!理论需要实例来验证,我首先想验证一个问题那就是弱引用数组中的缓存能被回收吗?我手动调用了GC,结果是没有被回收,我是如何验证的?我在布局中实现 了两个宽高一致的ImageView,再使用一个url来显示在他们两个之上,虽然会构建两个target,但是他们的key是一致的,所以A加载过并在显示中B再加载会从弱引用中获取,如果在A/B都加载过之后我调用了GC,理论上这时候被弱引用的缓存应该会被回收,但实际上我再次加载A,还是可以从弱引用中获取到缓存.注意这时我自己定义的一个弱引用对象是被回收掉的,真TM一脸懵逼,可能是我测试的方式有问题,但是我还没想到更好的测试方式,百度就算了,很多人知道是这样实现的但不会想为什么,有一部分人想到了,但是这些答案说服不了我,除非你有实例来验证你的说法
总结:Lrucache强引用缓存正在使用对象导致内存紧张时该对象无法被回收也就是EngineResource无法被回收,所以正在使用的图片使用弱引用对象缓存,至于在弱引用中被回收则会使用引用对象的key来清除数组中的映射,回收的是被引用的对象不是弱引用对象本身,Glide的弱引用对象是继承系统的,具体自行看源码吧,至于我上面的测试gc后EngineResource并没有被回收,这个问题我还没搞明白,蛋疼

ImageView宽高设置为wrap_content导致缓存失效的问题?

原因是高宽不固定虽然存入了缓存,但是再次into时由于宽高每次都不一致导致持续缓存,却获取不到,如果一定要使用wrap,可以跳过内存缓存磁盘缓存策略指定为SOURC,这样保守使用每次还是可以从硬盘中获取到原始图片,但不是最佳方案,因为每次还是都要处理图片再进行显示,远没有从内存中直接加载来的快,官方的说法是:

1.如果 View 的布局参数尺寸 > 0 且 > padding,则使用该布局参数;

2.如果 View 尺寸 > 0 且 > padding,使用该实际尺寸;

3.如果 View 布局参数为 wrap_content 且至少已发生一次 layout ,则打印一行警告日志,建议使用 Target.SIZE_ORIGINAL 或通过 override() 指定其他固定尺寸,并使用屏幕尺寸为该请求尺寸;

4.其他情况下(布局参数为 match_parent, 0, 或 wrap_content 且没有发生过 layout ),则等待布局完成,然后回溯到步骤1。

在RecyclerView 场景使用动画导致加载变慢的问题

Android的动画远比Glide图片解码等操作更加耗时,所以为了提升性能GlideV3需要禁止动画效果,GlideV4默认就是禁止的,官方建议使用preload体验会更好

Glide的内存缓存大小如何决定?

Glide的内存缓存使用Lru算法,由Glide的 MemorySizeCalculator 类来决定,这个类主要关注设备的内存类型,设备 RAM 大小,以及屏幕分辨率,用户也可以自定义缓存大小

Glide的磁盘缓存大小如何决定?

默认磁盘缓存大小为250MB,存在于缓存文件夹的特定目录,应用可以改动缓存大小及位置

GlideV3&GlideV4解码格式

GlideV3的解码格式是RGB_565,GlideV4为了解决特定的图片有明显的画质问题,默认解码格式改为ARGB_8888,当然你可以手动替换,前者对比于后者大概节省一半内存

GlideV4没有交叉淡入的过度效果了?

GlideV4不再默认应用交叉淡入或其他任何过渡效果,但是你可以手动配置

为什么我在RecyclerView中使用有卡顿?

1.请确认是否关闭了缓存,开启缓存明显提高速度
2.考虑使用override()加载更小的图片,
3.考虑使用preload预加载
4.注意少量的大图比大量的小图加载的更快,因为启动每个请求都需要相当多的开销

为什么我的Glide加载不出图片?

1.确认是否调用了into
2.确认view没有问题
3.确认view的宽高没有问题,如果指定为wrap_content,且父布局是wrap这也会导致Glide无法启动加载,
且view指定为wrap会导致每次加载的图片宽高不一致而导致缓存失效重复加载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值