当前位置:网站首页>Glide缓存机制
Glide缓存机制
2022-06-27 10:16:00 【橙子19911016】
1 Glide图片加载流程

- 封装参数:从指定来源到输出结果,中间可能经历很多流程,所以第一件事就是封装参数,这些参数会贯穿整个图片加载流程;
- 解析路径:图片的来源有很多种,格式也不尽相同,需要规范化;
- 读取缓存:为了减少计算,通常会做缓存,优先从缓存中读取;
- 查找文件/下载文件:如果是本地文件,直接解码即可,如果是网络图片,需要下载;
- 解码:
- 变换:解码出
Bitmap后,可能还需要做一些变换处理(圆角,滤镜等); - 缓存:得到最终的
Bitmap止呕,可以缓存起来,以便下次使用; - 显示:显示结果,可能需要做一些动画等;
2 Glide缓存机制简介
2.1 缓存的图片资源
- 原始图片(
Source) :即图片源的图片初始大小和分辨率; - 转换后的图片(
Result) :经过尺寸缩放和大小压缩等处理后的图片;
当使用Glide加载图片时,Glide会默认根据View视图对图片进行压缩和转换,而不显示原始图。(这也是Glide加载速度高于Picasso的原因)
2.2 缓存机制设计
Glide的缓存功能设计成二级缓存:内存缓存和硬盘缓存。(从网络加载不属于缓存)
- 内存缓存:防止重复将图片读入到内存,造成内存资源浪费,只缓存转换后的图片,而不是原始图片;
- 磁盘缓存:防止重复从网络或其他地方下载和读取数据,可缓存原始图片和转换过后的图片,用户自行设置;
在Glide中,缓存的读取顺序为:内存缓存 –> 磁盘缓存 –> 网络 ,内存缓存和磁盘缓存相互不影响,独立配置,内存缓存是默认开启的。
Glide的缓存机制使得Glide具备非常好的图片缓存效果,从而使得具备较高的图片加载效率。
以下是Glide的相关代码:
// 默认开启内存缓存,用户不需要作任何设置
Glide.with(this).load(url).into(imageView);
// 可通过API禁用内存缓存功能
Glide.with(this).load(url).skipMemoryCache(true) // 禁用内存缓存
.into(imageView);
Glide.with(this).load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE) // 不缓存任何图片,即禁用磁盘缓存
.into(imageView);
// DiskCacheStrategy.NONE:不缓存任何图片,即禁用磁盘缓存
// DiskCacheStrategy.ALL :缓存原始图片 & 转换后的图片
// DiskCacheStrategy.SOURCE:只缓存原始图片(原来的全分辨率的图像,即不缓存转换后的图片)
// DiskCacheStrategy.RESULT:(默认)只缓存转换后的图片(即最终的图像:降低分辨率后 / 或者转换后 ,不缓存原始图片
2.3 缓存类型
- 活动缓存(
ActiveResource):存储正在使用的图片; Lru内存缓存(LruResourceCache):图片解析完成后并最近被加载过会放到内存中;- 磁盘缓存-资源类型(
DiskCache - Resource):被解码后的图片写入磁盘文件中; - 磁盘缓存-原始数据(
DiskCache - Data):网络请求成功或在本地获取成功后,将原始数据在磁盘中缓存;
Lru(Least Recently Used):最近最少使用,它的核心思想是,当缓存满的时候,会优先淘汰最近最少使用的缓存对象。

2.3.1 内存缓存/运行时缓存
内存缓存/运行时缓存分为两部分:活动缓存(ActiveResource)和Lru内存缓存(LruResourceCache)。
LinkedHashMap继承自HashMap,在此基础上增加了双向链表的结构,每次访问数据的时候,会更新被访问的数据的链表指针。比如说从链表中删除并不是真正的删除数据,只是移动了链表的指针。

Lru内存缓存:使用LinkedHashMap来缓存资源(强引用),并设定一个缓存的大小。如果有资源被访问到,首先会在链表中删除该节点,然后再添加到链表头,这样就可以保证链表头部的节点是最近访问过的。而当缓存的数量达最大值的时候,就会将链表尾部(最近最少使用)的数据移除。
但是这样做有一个风险,就是容易将正在使用的资源回收掉。
Glide这样设计:从内存缓存(LruResourceCache)中拿到资源时候就主动添加到活动缓存(ActiveResource)中,并清理Lru内存缓存(LruResourceCache)中的资源,这样做的好处就是是保护正在使用资源不被Lru算法回收掉。
ActiveResources是一个弱引用的HashMap,用来缓存正在使用的图片,保存这个图片不会被Lru算法回收掉。图片用完之后会重新添加到Lru内存缓存中。
ActiveResources和LruResourceCache是内存缓存,属于运行时缓存且互斥(同一张图片不会同时缓存在ActiveResources和LruResourceCache中),应用被杀死后内存缓存将不存在。
2.3.2 磁盘缓存
磁盘缓存策略:
DiskCacheStrategy.NONE:表示不缓存任何内容;DiskCacheStrategy.RESOURCE:在资源解码后将数据写入磁盘缓存,即经过缩放等转换后的图片资源;DiskCacheStrategy.DATA:在资源解码前将原始数据写入磁盘缓存;DiskCacheStrategy.ALL:使用DATA和RESOURCE缓存数据;DiskCacheStrategy.AUTOMATIC:它会尝试对本地和远程图片使用最佳的策略。当加载远程数据时,AUTOMATIC策略仅会存储未被加载过程修改过的原始数据,因为下载远程数据相比调整磁盘上已经存在的数据要昂贵得多。对于本地数据,AUTOMATIC策略则会仅存储变换过的缩略图,因为即使需要再次生成另一个尺寸或类型的图片,取回原始数据也很容易。默认使用这种缓存策略;
在使用Glide去加载一张图片的时候,Glide默认不会将原始图片展示出来,而是会对图片进行压缩和转换。我们既可以缓存转换过的图片,也可以缓存转换之前的原始图片。
采用LRU算法的缓存有两种:LruCache和DisLruCache,分别用于实现内粗缓存和硬盘缓存。
3 大图加载
对于单个图片巨大,并且还不允许压缩。比如显示:世界地图、清明上河图、微博长图等。
首先不压缩,按照原图尺寸加载,那么屏幕肯定是不够大的,并且考虑到内存的情况,不可能一次性整图加载到内存中,所以这种情况的优化思路一般是局部加载,通过BitmapRegionDecoder来实现。BitmapRegionDecoder可以从图像中解码一个矩形区域,只显示图像的一部分。这种情况下通常Glide只负责将图片下载下来,图片的加载由自定义的ImageView来实现。
图片分块以后,每一块独立进行加载,并且加载bitmap是一个耗时操作,将加载bitmap异步实现。分块好后还有一个触发加载和回收的逻辑,原则是在它显示的范围内就触发加载,离开范围后就回收。
region [ˈriːdʒən] 地区,区域,界 decoder [diːˈkoʊdər] 解码器,译码器;译码员
参考
Glide 缓存总结(一)
Android源码分析:手把手带你分析 Glide的缓存功能
Glide源码之缓存机制Glide源码之缓存机制
Android Glide缓存机制及源码
浅谈Glide的原理
聊一聊关于Glide在面试中的那些事
【Android 内存优化】Bitmap 长图加载 ( BitmapRegionDecoder 简介 | BitmapRegionDecoder 使用流程 | 区域解码加载示例 )
学习笔记-android大图加载详解
如何解决android大量图片的帧动画卡顿和OOM问题?
边栏推荐
- Cross cluster deployment of helm applications using karmada [cloud native open source]
- Arduino PROGMEM静态存储区的使用介绍
- mongodb跨主机数据库拷贝以及常用命令
- C语言学习-Day_04
- C any() and aii() methods
- Queue, two-way queue, and its application
- R langage plotly visualisation: visualisation de plusieurs histogrammes normalisés d'ensembles de données et ajout d'une courbe de densité KDE à l'histogramme, réglage de différents histogrammes en ut
- On anchors in object detection
- .NET6接入Skywalking链路追踪完整流程
- [从零开始学习FPGA编程-47]:视野篇 - 第三代半导体技术现状与发展趋势
猜你喜欢

详细记录YOLACT实例分割ncnn实现

邮件系统(基于SMTP协议和POP3协议-C语言实现)

Comparison between new and old interfaces

CPU设计(单周期和流水线)

【TcaplusDB知识库】Tmonitor单机安装指引介绍(二)

CPU design (single cycle and pipeline)

Multi thread implementation rewrites run (), how to inject and use mapper file to operate database

User authentication technology

C语言学习-Day_06

新旧两个界面对比
随机推荐
For a moment, the ban of the US e-cigarette giant has been postponed, and products can be sold in the US for the time being
C language learning day_ 04
CPU design (single cycle and pipeline)
[200 opencv routines] 212 Draw a slanted rectangle
闭包的常见问题
go-zero微服务实战系列(七、请求量这么高该如何优化)
R语言plotly可视化:plotly可视化二维直方图等高线图、在等高线上添加数值标签、自定义标签字体色彩、设置鼠标悬浮显示效果(Styled 2D Histogram Contour)
C语言学习-Day_06
Error im002 when Oracle connects to MySQL
[noodle classic] Yunze Technology
Product strength benchmarking seal /model 3, with 179800 pre-sales of Chang'an dark blue sl03
【TcaplusDB知识库】Tmonitor单机安装指引介绍(一)
Leetcode to do questions
Quelles sont les fonctions de base nécessaires au développement d'applications de commerce électronique en direct? Quelles sont les perspectives d'avenir?
.NET 中的引用程序集
Queue, two-way queue, and its application
[STM32] Hal library stm32cubemx tutorial 12 - IIC (read AT24C02)
Feedforward feedback control system design (process control course design matlab/simulink)
Use of bufferedwriter and BufferedReader
并发,并行,异步,同步,多线程,互斥的概念