浅谈Glide图片缓存

字节Android岗面试必问:Glide的缓存机制,金三银四旗开得胜 } if (decodeFormat == null) { decodeFormat = DecodeFormat.DEFAULT; } return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat); } } 这里也就是构建Glide对象的地方了。那么观察第22行,你会发现这里new出了一个LruResourceCache,并把它赋值到了memoryCache这个对象上面... 阅读详情

关于上一篇大概走了一下Glide加载的基本流程,篇幅超长,没有耐心的人很难看完,所以我觉得这一片篇改变记录方案,走流程的事情就给有兴趣的人们吧!

简单了解缓存KEY

说到Glide的缓存那就要说缓存key,它的key是由十个参数来决定的,但是也就是为了是加载的图片唯一性罢了,看看源码吧:

 EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),
                loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),
                transcoder, loadProvider.getSourceEncoder());

Glide 的双缓存原理:

磁盘缓存:

一般的图片缓存指的就是磁盘缓存,把网络上的图片缓存到本地,这样就不需要每次都从网络加载,既提高了加载速度,又为用户节省了流量。

Glide在默认情况下是开启磁盘缓存的,而且提供了丰富的API来让开发者自己配置和管理磁盘缓存。

修改缓存位置和缓存大小:

我们要继承一个GlideModule的接口,然后实现他的两个方法如下:

public class DiskCacheMoudle implements GlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "glide_cache", 100 * 1024 * 1024));
        //builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, "glide_cache", 100 * 1024 * 1024));
    }
    @Override
    public void registerComponents(Context context, Glide glide) {
    }
}

可以看到我们new 出了一个InternalCacheDiskCacheFactory实例,那么我们可以去看看这个对象是怎么实现的

public final class InternalCacheDiskCacheFactory extends DiskLruCacheFactory {

    public InternalCacheDiskCacheFactory(Context context) {
        this(context, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR, DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE);
    }

    public InternalCacheDiskCacheFactory(Context context, int diskCacheSize) {
        this(context, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR, diskCacheSize);
    }

    public InternalCacheDiskCacheFactory(final Context context, final String diskCacheName, int diskCacheSize) {
        super(new CacheDirectoryGetter() {
            @Override
            public File getCacheDirectory() {
                File cacheDirectory = context.getCacheDir();
                if (cacheDirectory == null) {
                    return null;
                }
                if (diskCacheName != null) {
                    return new File(cacheDirectory, diskCacheName);
                }
                return cacheDirectory;
            }
        }, diskCacheSize);
    }
}

很简单,就是获取到应用的内部存储,如果不想存储在内存,就可以使用与之对应的ExternalCacheDiskCacheFactory类,我们在这两个类中可以看到有一个静态的DiskCache.Factory方法,跟进去可以看到Glide默认的缓存大小是250M;缓存的文件名是:”image_manager_disk_cache”,如果不想缓存在内部或者外部,那么你就可以自己设置一个目录方法如下:

builder.setDiskCache(
                new DiskLruCacheFactory(new DiskLruCacheFactory.CacheDirectoryGetter() {
                    @Override
                    public File getCacheDirectory() {
                        return getMyCacheLocationBlockingIO();
                    }
                }), 100 * 1024 * 1024);

通过网上查询,getMyCacheLocationBlockingIO()方法返回的文件不能为空,并且只能是一个建立了的文件夹,不能是文件;(所以感觉这个用处好像不大);

磁盘缓存策略

先普及一下Glide中的四种缓存策略:
- DiskCacheStrategy.NONE 不缓存文件
- DiskCacheStrategy.SOURCE 只缓存原图
- DiskCacheStrategy.RESULT 只缓存最终加载的图(默认的缓存策略)
- DiskCacheStrategy.ALL 同时缓存原图和结果图

什么是原图?什么是结果图?

假如你要加载的图片分辨率为1000x1000,但是最终显示该图片的ImageView大小只有500x500,那么Glide就会只缓存500x500的小图。这也是在从磁盘缓存中加载图片时Glide比Picasso快的原因。
如果你想改变缓存策略只要:(我随机选择的)

Glide.diskCacheStrategy(DiskCacheStrategy.ALL)
磁盘缓存算法

在Glide中磁盘缓存默认使用的是LRU(Least Recently Used)算法。如果你想使用其他的缓存算法,就只能通过实现DiskCache接口来完成了。

内存缓存:

  • 由于Glide 默认是开启内存缓存的,(skipMemoryCache(true)关闭)。
  • 缓存的Glide里面使用内存缓存是使用了一个叫BitmapPool的对象,从名字就可以看出这是一个bitmap池,里面有几个可以复用的对象。
  • 使用了LruCache算法。
  • 使用了弱引用机制(代码如下)
public class Engine implements EngineJobListener,
        MemoryCache.ResourceRemovedListener,
        EngineResource.ResourceListener {

    private final MemoryCache cache;
    private final Map<Key, WeakReference<EngineResource<?>>> activeResources;
    、
    、
    、

    private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {
        if (!isMemoryCacheable) {
            return null;
        }
        EngineResource<?> cached = getEngineResourceFromCache(key);
        if (cached != null) {
            cached.acquire();
            activeResources.put(key, new ResourceWeakReference(key, cached, getReferenceQueue()));
        }
        return cached;
    }

    private EngineResource<?> getEngineResourceFromCache(Key key) {
        Resource<?> cached = cache.remove(key);
        final EngineResource result;
        if (cached == null) {
            result = null;
        } else if (cached instanceof EngineResource) {
            result = (EngineResource) cached;
        } else {
            result = new EngineResource(cached, true /*isCacheable*/);
        }
        return result;
    }

    private EngineResource<?> loadFromActiveResources(Key key, boolean isMemoryCacheable) {
        if (!isMemoryCacheable) {
            return null;
        }
        EngineResource<?> active = null;
        WeakReference<EngineResource<?>> activeRef = activeResources.get(key);
        if (activeRef != null) {
            active = activeRef.get();
            if (active != null) {
                active.acquire();
            } else {
                activeResources.remove(key);
            }
        }
        return active;
    }
    、
    、
}

当从LruResourceCache中获取到缓存图片之后会将它从缓存中移除,然后将这个缓存图片存储到activeResources当中。activeResources就是一个弱引用的HashMap,用来缓存正在使用中的图片。

内存缓存并不是不可修改的,我们可以通过修改Bitmappool的大小来修改:

builder.setMemoryCache(new LruResourceCache(yourSizeInBytes));//修改内存
builder.setBitmapPool(new LruBitmapPool(sizeInBytes));//修改缓存池

默认的内存缓存和BitmapPool的大小由MemorySizeCalculator根据当前设备的屏幕大小和可用内存计算得到。同时Glide还支持动态的缓存大小调整,在存在大量图片的Activity/Fragment中,开发者可以通过setMemoryCategory方法来提高Glide的内存缓存大小,从而加快图片的加载速度。

同理,磁盘缓存策略有四种策略,内存同样也有三中策略:
MemoryCategory有3个值可供选择:
- MemoryCategory.HIGH(初始缓存大小的1.5倍)
- MemoryCategory.NORMAL(初始缓存大小的1倍)
- MemoryCategory.LOW(初始缓存大小的0.5倍)

总结

看这个样子两级缓存也是参照了计算机操作系统中的三级缓存思想了,不得不说这是一个天才级的想法,以后可以多多使用,有兴趣的人可以自己谢谢两级缓存加深下理解,当然也可以参照下我当时联系的时候写的那个MyImageloader。

GitHub连接: https://github.com/wangjiapu/MyImageloager

Glide框架解析---缓存机制介绍及活动缓存 内存缓存 复用池相关类(一) Glide是一个非常成熟的图片加载框架了,一开始从事Android开发就一直使用这个框架,使用的很熟,但是原理和源代码上就没怎么研究了,最近抽出时间来,好好的学习了Glide的源码和原理,我把自己的学习成果分享给大家。因为Glide的原理相对比较复杂,一篇博客很难把Glide说清楚,所以之后我会按照顺序分享6-8篇博客,手写一个阉割版的Glide。 今天我先简单介绍一下Glide的缓存机制及写一... 阅读详情

相关推荐

Android——Glide加载网络图片——缓存

利用Glide实现图片的三级缓存 图片加载框架之所以高效,是因为它不但封装了访问网络的步骤,而且引入了三级缓存机制。 缓存过程说明如下:(1)先到内存(运存)中查找图片;(2)有找到就直接显示内存图片,没找到的话再去磁盘(闪存)查找图片;(3)在磁盘能找到就直接显示磁盘图片,没找到的话再去请求网络; 如此便形成“内存→磁盘→网络”的三级缓存。 Glide的缓存参数设置方法 Glide使用Req...

小白龙白龙马的博客 1535

Glide缓存机制

当使用加载图片时,会默认根据视图对图片进行压缩和转换,而不显示原始图。(这也是加载速度高于的原因)的缓存功能设计成二级缓存:内存缓存和硬盘缓存。(从网络加载不属于缓存)在中,缓存的读取顺序为:,内存缓存和磁盘缓存相互不影响,独立配置,内存缓存是默认开启的。的缓存机制使得具备非常好的图片缓存效果,从而使得具备较高的图片加载效率。以下是的相关代码: 2.3 缓存类型 活动缓存():存储正在使用的图片; 内存缓存():图片解析完成后并最近被加载过会放到内存中; 磁盘缓存-资源类型():被解码后的图片写入磁盘文件

xingyu19911016的博客 6089

详解Unity中的粒子系统Particle System (三)

上一篇我们详细讲解了有关主模块的全部内容,已经对粒子系统的基本运作有了足够的了解,本篇就来讲一下被粒子系统默认启用的Emission、Shape、Renderer模块又在粒子系统中扮演着怎么样的作用吧。

梦小天幼的博客 1万+

Glide系列(四) — Glide缓存流程分析

Glide 是一个图片加载库,跟它同类型的库还有 Picasso、Fresco、Universal-Image-Loader 等。基于 Glide 优秀的缓存管理策略和生命周期关联的特点,目前市面上对 Glide 的使用非常广,因此我们有必要深入研究下 Glide 相关的实现原理,便于更好的使用它。

Elson的博客 1982

Android15 AndroidV冻结和解冻的场景

cgroup 最初由 Google 工程师 Paul Menage 和 Rohit Seth 在 2006 年提出,是一种细粒度资源控制的Linux内核机制。于 2007 年合并到 Linux 内核主线中。然而 Google 原生系统直到 Android 11 或更高版本上才支持 CACHE 应用的 CPU 冻结功能。当应用切换到后台并且没有其他活动时,系统会在一定时间内通过状态判断,将进程 ID 迁移到冻结的 cgroup 节点上,实现冻结 CACHE 应用。

苏法迪的专栏 1787

从BUCK-BOOST到反激:一个‘拆电感’的视角,轻松理解多路输出交叉调整

本文从BUCK-BOOST电路到反激变换器的演变入手,通过‘拆解电感’的独特视角解析多路输出交叉调整机制。深入探讨了反激电路的能量暂存方式、传递路径变化及电压关系,并结合具体参数对比揭示其特性。针对多路输出中的电压平衡问题,提供了绕组排布优化、元器件选型等实战技巧,帮助工程师有效提升电源系统的稳定性与效率。

weixin_33738578的博客 437

浅谈Glide缓存的大小以及清除缓存

在目前很多图片加载框架的实现中,我们选择了Glide就需要对其有一个深度的了解。在看完别的大神的代码和源码之后,有了以下的感想,给大家提供一个Glide的缓存的工具类。 在开始书写工具类之前,我们应该使用目前版本最高的Glide依赖 compile 'com.github.bumptech.glide:glide:3.7.0' 添加如上依赖之后,新建一个工具类,具体代码如下:

m0_37756225的博客 4897

高通跃龙QCS6490部署yolov11_obb实战:QNN SDK工具链全解析与避坑指南

本文详细解析了在高通跃龙QCS6490平台上部署yolov11_obb模型的实战过程,重点介绍了QNN SDK工具链的使用与优化技巧。从环境配置、模型转换到性能调优,提供了全面的避坑指南和DSP加速配置建议,帮助开发者高效实现旋转框检测任务在边缘设备上的部署。

weixin_29232121的博客 305

浅谈AsyncImageLoader和Glide加载本地图片性能对比

距离上一次写博客已经很长时间,主要原因还是因为太懒了,而最近心思又不在技术上所以才长时间没有跟新博客。这篇文章来简单说说Glide和AsyncImageLoader加载本地图片上的表现吧。 关于Glide的用法及源码解析可以参考郭霖大神的Glide博客专栏,虽然专栏中是以Glide 3.x版本进行源码解析的,但是对于Glide 4.x源码也就是大同小异了。 1、AysncImageLoader说明...

Yoryky的专栏 1377

实战教程:如何用Python+小波变换+CNN搞定医学影像中的条纹噪声(附完整代码)

本文提供了一套完整的实战方案,指导如何利用Python结合小波变换与卷积神经网络(CNN)去除医学影像中的条纹噪声。该方法通过小波变换精准定位噪声,再使用轻量化CNN进行针对性清除,有效保护图像细节,并附有可运行的完整代码,为医学影像处理与AI分析提供高效工具。

weixin_29056101的博客 269

从零开始,手把手教你用RTL代码设计一个简单的8位CPU(附状态图与ALU设计)

本文详细介绍了如何从零开始设计一个简单的8位CPU,包括状态机设计、ALU实现与RTL编码实战。通过具体的指令集分析、状态图设计和Verilog代码示例,帮助读者深入理解CPU工作原理,并掌握RTL代码编写技巧。特别适合计算机系统学习者和硬件设计爱好者。

weixin_30847063的博客 320

浅谈Glide加载图片的框架和封装

最近打算想把图片的加载框架Glide运用到自己的项目中,于是上网查了一下资料,学习了它的一些基本用法,并对其进行了简单的封装。 先上图看看效果:

wyb112233的专栏 4134

核磁共振常用的文件格式介绍:NIfTI volume 格式 (*.nii), GIFTI 格式 (*.gii), CIFTI 格式 (*.nii)

NIfTI volume 格式 (*.nii)GIFTI 格式 (*.gii)CIFTI 格式 (*.nii)Scene file文件 (*.scene)规格文件 (*.spec)解剖 (*.annot)一个场景文件包含一个或多个场景;每个场景实际上是保存时 wb_view 内部状态的快照。这包括有关加载哪些文件、如何显示、如何配置选项卡的信息(选择了哪些表面、在每个层中选择了哪些文件、打开了哪些层、哪些视图旋转、调色板设置、平铺选项卡等),以及在它们上面添加了哪些注释(文本、箭头、圆圈等)。

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 3043

图片加载优化+glide配置 浅谈

里可以替换或插入组件,实现自定义的数据加载与解码链路。思路:自定义一个 Loader,让 Glide 在加载。」,避免频繁创建/销毁导致的内存抖动与 GC。Glide 通常通过自定义。来做全局配置,核心关注点是。

wordending的博客 401

社区版 ABAP MCP 能不能读取 SAP S/4HANA 公有云开发对象,我的判断是能试,但不能当成已被 SAP 背书的标准通道

文章摘要:当前存在多个社区项目(如mcp-abap-adt、mcp-abap-abap-adt-api等)通过包装ABAP ADT能力为MCP Server,使AI开发工具能读取ABAP对象。这些项目技术上依赖ADT HTTP API或SAP官方ADT language server,但针对SAP S/4HANA Cloud Public Edition的完整适配仍存在挑战。SAP官方已通过VS Code扩展提供ADT MCP能力,而社区方案在云环境下需遵循ABAP Cloud的严格限制,仅能访问已授权的开

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 87

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Glide

标题标题重点内容 开始新的系列,Glide的基本用法 Android图片加载框架最全解析(一),Glide的基本用法 图片加载框架最全解析(二),从源码的角度理解Glide的执行流程 Android图片加载框架最全解析(三),深入探究Glide的缓存机制 Android图片加载框架最全解析(四),玩转Glide的回调与监听 Glide 一个专注于平滑滚动的图片加载和缓存库 Glide,Picas

ThePromonkeyOf_HeLuo的博客 470

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Android 缓存浅谈(二) DiskLruCache

上篇文章讲解了使用LruCache策略在内存中缓存图片,如果你还未了解,请先看Android 缓存浅谈(一) LruCache。      在Android应用开发中,为了提高UI的流畅性、响应速度,提供更高的用户体验,开发者常常会绞尽脑汁地思考如何实现高效加载图片,而DiskLruCache实现正是开发者常用的图片缓存技术之一。Disk LRU Cache,顾名思义,硬件缓存,就是一个在文件系

程序员七哥 5491

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

浅谈 Glide - BitmapPool 的存储时机 & 解答 ViewTarget 在同一View显示不同的图片时,总用同一个 Bitmap 引用的原因...

作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguanh/ GitHub : https://github.com/af913337456/ 腾讯云专栏: https://cloud.tencent.com/developer/user...

weixin_34290000的博客 218

浅谈 Glide - BitmapPool 的存储时机 & 解答 ViewTarget 在同一View显示不同的图片时,总用同一个 Bitmap 引用的原因...

作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguanh/ GitHub : https://github.com/af913337456/ 腾讯云专栏: https://cloud.tencent.com/developer/use...

weixin_34296641的博客 215

浅谈Android生产者消费者模式

运用生产者消费者模式实现图片异步加载。

郭霖 2279

Android伸手党系列之四:Android项目开发常用技术

这篇收集Android开发常用技术谈谈MVP架构浅谈 MVP in Android --推荐不要再给MVP中Presenter写接口了T-MVP:泛型深度解耦下的MVP大瘦身Android框架模式(1)-MVP入门Android日志Log最佳实践OkHttpOkHttp使用Android OkHttp完全解析 ...

QY'UniverseSpace的博客 3243

浅谈Android应用开发中的app架构设计

  作为2017年的首篇博客,定然要来点全局性的料,不过作为一名从事Android开发稍有经验却又不敢称大的开发者来讲,又必须要说出个子丑寅卯来,所以定了这个标题。本篇简单介绍一下个人对app架构的理解,如有纰漏,望留言指正交流。   首先,APP进行架构设计的目的何在?   在我刚开始写APP时,只是注重界面设计和逻辑跳转,至于如何节省时间的敲代码没有太多的了解。(当然这也练就了一身的手速)...

weixin_34129696的博客 171

5年 Android 面试题

感谢提供面试题汇总 五年面试题汇总 5年Android面试题汇总GC原理,有哪几种GC方式1、标记清除算法2、复制算法3、标记压缩算法4、分代算法Minor GC存在的问题注释HashMap原理HashMap原理 GC原理,有哪几种GC方式 GC原理,有哪几种GC方式 GC回收机制分为四种方式 标记清除算法 复制算法 标记压缩算法 分代算法 GC的出现解放了程序员需要手动回收内存的苦恼,但我们也是要了解GC的,知己知彼,百战不殆嘛。 常见的GC回收算法主要包括引用计数算法、可达性分析法、标记清.

Blog_Sun的博客 1577
上一篇: 浅探Glide加载流程源码
下一篇: 线程与锁
coding_p
博客等级 码龄11年 10粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值