当前位置:首页 » 硬盘大全 » glide缓存图片命名规则
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

glide缓存图片命名规则

发布时间: 2023-05-06 10:03:53

A. Glide图片加载的用法介绍和三级缓存实现

Glide库是用来实现图片加载的框架,功能强大且易使用,深受大家喜爱。

为啥要做缓存? android默认给每个应用只分配16M的内存,所以如果加载过多的图片,为了 防止内存溢出 ,应该将图片缓存起来。

图片的三级缓存分别是:

1、内存缓存
2、本地缓存
3、网络缓存
其中,内存缓存应优先加载,它速度最快;本地缓存次优先加载,它速度也快;网络缓存不应该优先加载,它走网络,速度慢且耗流量。

最优-优先级:内存缓存 > 本地缓存 > 网络缓存

两个方法实现:根据图片的url去加载图片、在本地和内存中缓存

两个方法实现:设置本地缓存,以及获取本地缓存

两个方法实现:设置内存缓存,获取内存缓存。

如果使用hashmap去存储图片时,当图片越来越多,那么会造成内存溢出,因为是强引用(对于强引用的系统不会回收)

如果改成软引用softReference,在android 2.3 以上的系统,对象会被提前回收。

可以用LruCache来解决上述内存不回收或提前回收的问题。least recentlly use 最少最近使用算法 它会将内存控制在一定的大小内, 超出最大值时会自动回收, 这个最大值开发者自己定。(这个东西没有用过..)

参考链接: https://blog.csdn.net/sinat_20645961/article/details/46325243

B. Glide ② — 缓存机制

阅读本文需要先了解 Glide加载流程

首先介绍一下Glide中对图片资源的封装类: EngineResource

在活动缓存中,使用了一个map用来存放EngineResource对象,这里需要注意一个操作,就是这个EngineResource对象是用WeakReference包裹的,并且通过ReferenceQueue监听了EngineResource的回收,在回收的时候会清理当前的活动缓存内容;
下面分析一下源码是如果实现的:
首先,自定义一个WeakReference类,将key和resource传进入(用于在WeakReference回收的时候释放),传入一个ReferenceQueue对象,用于监听WeakReference回收

开启一个子线程,在循环中监听ReferenceQueue的返回值,通过这个返回值,判断WeakReference有没有回收,监听的方法是ReferenceQueue.remove(),这是一个阻塞方法;所以要开子线程;

LruResourceCache继承了LruCache类,关于LruCache类,简单提一下,具体的可以参考我之前的博客 LruCache实现 ,LruCache继承了LinkedHashMap,LinkedHashMap有一个特点,就get后的数据会移动到队列,这就是Lru思想:固定一个容量,put的时候如果超过容量了,将最后一个节点删除,get的时候将get的这个节点移动到队列的头部;

onItemEvicted()方法是LruCache的一个空方法,调用的时机是在put的时候判断是否超过容量,如果超过容量了,就淘汰最后一个节点,并调用这个方法;

活动缓存和内存缓存都是缓存在内存中的,活动缓存缓存的是正在使用的图片资源,当图片不使用时会放到内存缓存中,提出活动缓存的目的:单一的内存缓存由于Lru的淘汰机制会导致图片加载不稳定

首先介绍一个磁盘缓存方案DiskLruCache(非Google官方编写,但获得官方认证),关于这个磁盘缓存方案的理解可以看郭林的这片文章:
Android DiskLruCache完全解析,硬盘缓存的最佳方案

从上一篇文章知道,Glide加载操作是通过 Engine 来驱动的

Engine的load()中,首先尝试从 活动缓存 和 内存缓存 获取缓存,如果没有缓存再启动EngineJob和DecodeJob; 上面介绍了缓存的获取,下面看一下缓存的存放,肯定是在获取到图片后的回调中存放的

在DecodeJob获取到图片数据后,会回调很多接口,在回调中会将其放入 活动缓存 ,当图片不在使用的时候,就会放入内存缓存,根据上面介绍的活动缓存规则,当 EngineResource 计数为0时就应该放入内存缓存;

当资源引用为0,回调onResourceReleased(),从活动缓存移除,放入内存缓存;

上面介绍了活动缓存和内存缓存的存放和获取,下面看一看磁盘缓存的存取;

还记得 DataFetcherGenerator 接口吗?这个接口是DecodeJob用于获取数据的,有三个具体的实现:

我们在上一篇具体介绍的是网络文件的获取,这里的磁盘缓存使用的就是 DataCacheGenerator(缓存文件) 这个Generator了

上篇文章知道DecodeJob是一个Runnable任务,在run()会调用runWrapped(),在runWrapped()中会做三种事情:

在runWrapped()的解码操作中会执行decode(),在decode()中,会disk put操作;

Glide的磁盘缓存是基于DiskLruCache 实现的,Glide直接使用的是DiskLruCacheWrapper对象对DiskLruCache 的封装;

C. glidecache是什么文件夹

glidecache是图片缓存的文件夹,该文件夹可以删除,但是删除的同时会删除手机中的缓存图片,通过删除此文件夹删除的缓存图片无法找回,一旦删除无法恢复。

手机缓存是数据交换的缓冲区,缓存是CPU的一部分,它存在于CPU中,而CPU存取数据的速度则非常的快,一秒钟能够存取,处理十亿条指令和数据。

而内存就慢很多,缓存是为了解决CPU速度和内存速度的速度差异问题,在打开文件时,系统会将数据从内存中复制到一个缓冲区而再打开文件时,系统会直接读取缓存中的数据,则不用到内存中读取, 这样浏览文件的速度会比较快。

D. Glide 图片库原理(三)缓存机制

查找缓存使用

用完移除

源码中查看EngineKey-----相当于key,算法序列abcdsxxfaskldfjklf...
源码中查看Source-----相当于value(Bitmap),调用系统转换成Bitmap

情景: 相册类的App经常需要同时展示大量的图片,这种情况下图片的质量可以低一点,因为加载速度优先于图片的质量。

解决办法: 我们可以设置译码的格式,在RequestOptions中加入.encodeFormat(Bitmap.CompressFormat.WEBP).encodeQuality(10))的选项,①encodeFormat的参数有Bitmap.CompressFormat.PNG,Bitmap.CompressFormat.JPEG,Bitmap.CompressFormat.WEBP(质量从高到低);②encodeQuality设置的是0-100的int类型,一个质量百分比参数,越小质量越低。

情景: 大体的意思应该是同一个URL在不同的时间可能会指向不同的资源,所以同样需要实时更新。

解决办法相同

情景: 开发一款有头像的APP,我们修改了头像并且更新到了服务端,可是当我们点击查看大图时加载出来的还是原来的头像。

解决办法: 这是Glide强大的缓存带来的副作用,我们可以在RequestOptions中加入.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)的选项。那么缓存的功能就会全部关闭,从而使得每次都是从服务端加载,所以头像会是最新。

情景: 省流量模式的应用情景就是减少不必要图片的加载。

解决办法: 我们可以在RequestOptions中加入onlyRetrieveFromCache(true)的选项。那么图片就只会从缓存中读取,如果没有缓存则不加载图片,从而达到减少流量消耗的目的。

E. Android-Glide的缓存机制

很多小伙伴都在使用 Glide 加载图片,出去面试的时候肯定会被问蔽备起,“Glide缓存机制,你了解多少?”。这篇博客我来说说我了解到的 Glide 的缓存机制。

默认情况下,Glide 会在开始一个新的图片请求之前检查以下多级的缓存:
1.活动资源 (Active Resources) - 现在是否有另一个 View 正在展示这张图片?
2.内存缓存 (Memory cache) - 该图片是否最近被加载过并仍存在于内存中?
3.资源类型(Resource) - 该图片是否之前曾被解码缓让、转换扰并局并写入过磁盘缓存?
4.数据来源 (Data) - 构建这个图片的资源是否之前曾被写入过文件缓存?

设置内存缓存开关:

设置磁盘缓存模式:

可以设置4种模式:

F. Glide获取图片缓存文件名Key

最近项目由于需要支持gif动图,所以把图片加载框架由 ImageLoader 切换到 glide ,因为需要支持长按保存图片,所以就需要找到 glide 加桥搭帆载后缓存的图片路径。
根据网上资料,最终找到 Glide 最终生成path的路径为: /data/枝没data/your_packagexxxxxxx/cache/image_manager_disk_cache
对应的生成规则: com.bumptech.glide.load.engine.EngineKey#updateDiskCacheKey
问题转换为:获取url到缓存文件path的生成规则算法上
直接把获取函数贴出敏雹来:

G. Glide图片缓存策略

Glide四级缓存:

先找内存,再找文件

1)活动缓存(活动资源):ActiveResource,里边使用一个弱衫闷引用weakHashMap来保存正在使用的图片,当我们加载图歼袜片的时候,先从activeResource里边去查找,如果找不到的话就从内存缓存里查找。理论上没有大小限制,但是因为是弱引用管理的,所以是可回收的。 存活于内存当中,非持久化

2)内存缓存:默认使用的是LRU的memoryCache,如果没有找到,将从文件缓存中查找。 存活于内存当中,非持久化。

3)文件缓存:先从资源类型文件里查找(经过了圆角缩放处理的),然后从数据来源文件(未经过处理)里查找, 存活于磁盘中,持久化

这种框架的基本思路:源码的三条主线

(1)请求是怎样发送的?

(2)请求是怎样处理的?

(3)或改弯请求是怎样维护的?

Glide.with(context)  ---->构建一个RequestManager

.load()  ------------->输入数据模型,创建一个RequestBuilder,建造者模式

.into()------->调用RequestBuilder的load方法,buildRequest方法,传入target,