Android | Glide3与Glide4缓存配置

  磁盘缓存、内存缓存与BitmapPool都是使用LRU算法,Glide维护每个缓存的引用计数,当缓存将超过容量限制时,引用计数最少的缓存被释放。

磁盘缓存(Disk Cache)

  • 默认配置
    1、存储位置:内部存储
    2、最大LRU磁盘缓存容量:250MB(DEFAULT_DISK_CACHE_SIZE
    3、路径名:“image_manager_disk_cache”(DEFAULT_DISK_CACHE_DIR
  • 修改配置
//内部存储
builder.setDiskCache(
  new InternalCacheDiskCacheFactory(context, cacheDirectoryName, yourSizeInBytes));

//外部存储
builder.setDiskCache(
  new ExternalCacheDiskCacheFactory(context, cacheDirectoryName, yourSizeInBytes));

//InternalCacheDiskCacheFactory为内部存储,ExternalCacheDiskCacheFactory为外部存储
//cacheDirectoryName:配置路径名
//yourSizeInBytes:配置最大容量
  • 修改磁盘缓存策略
v3
缓存策略 描述
ALL 同时保存未修改的原始图片与修改后的图片
NONE 取消磁盘缓存
SOURCE 仅保存未修改的原始图片
RESULT(默认) 仅保存修改后的图片
Glide.with(fragment)
  .load(url)
  .diskCacheStrategy(DiskCacheStrategy.ALL)
  .into(imageView);
v4
缓存策略 描述
ALL 对于远程图片,同时保存未修改的原始图片和修改后的图片;对于本地图片,仅保存修改后的图片
NONE 取消磁盘缓存
DATA 仅保存未修改的原始图片
RESOURCE 仅保存修改后的图片
AUTOMATIC(默认) 默认情况与ALL相同
GlideApp.with(fragment)
  .load(url)
  .diskCacheStrategy(DiskCacheStrategy.ALL)
  .into(imageView);
  • 清理磁盘缓存(在后台线程)
Glide.get(applicationContext).clearDiskCache();
  • 仅从磁盘或内存缓存中获取(v4有效)
GlideApp.with(this)
                .load("")
                .onlyRetrieveFromCache(true)
                .into(imageView)

内存中缓存

  • 系统划分给进程的可用内存容量:基于硬件不同,取值为16MB、24MB或者更高。
  • Glide从可用内存容量中取一部分作为最大内存占用量:
v3
设备 最大内存占用量
低内存设备 可用内存容量*0.33F
非低内存设备 可用内存容量*0.4F
v4
设备 默认最大内存占用量 可自定义最大内存占用量
低内存设备 可用内存容量*0.33F 可用内存容量*比例
非低内存设备 可用内存容量*0.4F 可用内存容量*比例
  • 最大内存占用量分配给内存缓存与位图池缓存

  显示一个屏幕所有像素需要的内存为screenSize。

v3
未超过最大内存占用量 超过最大内存占用量
Memory Cache screenSize*2屏 最大内存占用量*2/6
BitmapPool screenSize*4屏 最大内存占用量*4/6
v4

Android O之前

未超过最大内存占用量 超过最大内存占用量
Memory Cache screenSize*2屏 最大内存占用量*2/6
BitmapPool screenSize*4屏 最大内存占用量*4/6

Android O之后

未超过最大内存占用量 超过最大内存占用量
Memory Cache screenSize*2屏 最大内存占用量*2/3
BitmapPool screenSize*1屏 最大内存占用量*1/3

v4可用自定义屏幕数

  • 动态调整容量
Glide.get(context).setMemoryCategory(MemoryCategory);
MemoryCategory 描述
LOW 使用初始容量的一半
NORMAL 使用初始容量
HIGH 使用初始容量的1.5倍

内存缓存(Memory Cache)

  • 配置初始容量
v3
builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize );
v4
builder.setMemoryCache(new LruResourceCache(customMemoryCacheSize );

  或

MemorySizeCalculator.Builder builder= new MemorySizeCalculator.Builder(context);
builder.setMemoryCacheScreens(int);//内存缓存的屏数
builder.setBitmapPoolScreens(int);//BitmapPool的屏数
builder.setMaxSizeMultiplier(float);//从进程可用内存划分的比例
builder.setLowMemoryMaxSizeMultipiler(float);//低内存设备时从进程可用内存划分的比例
builder.setMemoryCache(builder.build().getMemoryCacheSize());
  • 取消内存缓存
v3
Glide.with(fragment)
  .load(url)
  .skipMemoryCache(false)
  .into(imageView);
v4
GlideApp.with(fragment)
  .load(url)
  .skipMemoryCache(false)
  .into(imageView);
  • 清理内存缓存(在主线程)
Glide.get(applicationContext).clearMemory();

位图池缓存(BitmapPool)

  • 配置初始容量
v3
builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize ));
v4
builder.setBitmapPool(new LruBitmapPool(customBitmapPoolSize ));

  或

MemorySizeCalculator.Builder builder= new MemorySizeCalculator.Builder(context);
builder.setMemoryCacheScreens(int);//内存缓存的屏数
builder.setBitmapPoolScreens(int);//BitmapPool的屏数
builder.setMaxSizeMultiplier(float);//从进程可用内存划分的比例
builder.setLowMemoryMaxSizeMultipiler(float);//低内存设备时从进程可用内存划分的比例
builder.setMemoryCache(builder.build().getBitmapPoolSize());

缓存刷新问题

  因为磁盘缓存使用的是哈希键,所以并没有一个比较好的方式来简单地删除某个特定url或文件路径对应的所有缓存文件。如果你只允许加载或缓存原始图片的话,问题可能会变得更简单,但因为Glide还会缓存缩略图和提供多种变换(transformation),它们中的任何一个都会导致在缓存中创建一个新的文件,而要跟踪和删除一个图片的所有版本无疑是困难的。
  使用签名插入到哈希键中来控制缓存刷新。

GlideApp.with(fragment)
    .load(mediaStoreUri)
    .signature(new MediaStoreSignature(mimeType, dateModified, orientation))
    .into(view);
MediaStoreSignature(String mimeType, long dateModified, int orientation)
StringSignature(String signature)
v4
ObjectKey(Object object)

v3和v4的配置API差异

v3

  v3使用GlideModule接口实现懒配置,步骤:

  • 1、实现GlideModule接口,在applyOptions(…)方法中应用配置选项(如缓存配置选项),在registerComponents(…)方法中注册ModelLoaders;
  • 2、添加对GlideModule接口的混淆忽略;
  • 3、在AndroidManifest.xml中的<application>下添加meta-data,name属性值为类名,value属性值固定为“GlideModule”。

  所谓懒配置,即直到应用首次发起Glide请求,才会自动地进行配置。Glide先遍历AndroidManifest.xml中<application>下所有的<meta-data>,匹配value为“GlideModule”的meta-data。再利用其中的name属性,通过反射机制得到该GlideModule子类的实例。(源码:ManifestParser类)

v4

  v4使用编译时注解避免运行时遍历meta-data的过程。
  v3使用一个或多个GlideModule完成配置,v4使用有且只有一个AppGlideModule加可选的多个LibraryGlideModule完成配置。
  v4的注解编译器在编译时汇总AppGlideModule类和LibraryGlideModule类中的配置逻辑,生成类名为GeneratedAppGlideModuleImpl的配置类。在运行时懒配置触发时,Glide反射这个自动生成的类,完成配置。
  步骤:

  • 1、实现AppGlideModule接口,在applyOptions(…)方法中应用配置选项(如缓存配置选项),在registerComponents(…)方法中注册ModelLoaders;
  • 2、可选地实现LibraryGlideModule接口,在registerComponents(…)方法中注册ModelLoaders;
  • 3、实现AppGlideModule和LibraryGlideModule接口时需要添加@GlideModule注解
  • 4、添加混淆忽略

  v4关闭解析AndroidManifest.xml的步骤:重写AppGlideModule#isManifestParsingEnabled(),返回false。


推荐阅读


感谢喜欢!你的点赞是对我最大的鼓励!欢迎关注彭旭锐的简书!

推荐阅读更多精彩内容