使用 Glide 进行图像缓存签名和元数据

3

用户可以更改图片(替换)。一旦用户更改了他们的图像,我希望新的图像被缓存在Glide中,并将旧图像从缓存中清除。

我已经阅读了网上的所有内容,但仍然不知道如何实现一个好的解决方案。

我尝试跳过本地内存和磁盘缓存,就像设置图像时一样:

GlideApp.with(fragment)
  .load(url)
  .diskCacheStrategy(DiskCacheStrategy.NONE)
  .skipMemoryCache(true)
  .into(view);

这个解决方案很慢,因为它每次都会调用新图像 - 它从不缓存新图像。

Glide文档说:

当内容更改时(url、uri、文件路径等),使缓存文件失效的最佳方法是在可能的情况下更改标识符。 - https://github.com/bumptech/glide/wiki/Caching-and-Cache-Invalidation

但对我来说不可能实现,因此Glide文档接着说:

由于更改标识符通常很困难或不可能,Glide还提供了signature() API,以将您控制的其他数据混入到缓存键中。

并给出了以下示例:

Glide.with(yourFragment)
    .load(yourFileDataModel)
    .signature(new ObjectKey(yourVersionMetadata))
    .into(yourImageView);

但是问题来了。什么是好的“你的版本元数据”?我该如何创建和维护它?我看到过以下示例:

.signature(new ObjectKey(Long.toString(System.currentTimeMillis())))

这会导致磁盘缓存密钥每次加载图像时都会更改,因此很慢。我只需要在用户替换图像时更改密钥,而不是每次加载图像时都更改。

有人写道:

你可以做一些像生成新的UUID或每当图像更改时增加一个整数的事情。如果你选择这条路,你需要在某个地方跟踪每个图像的当前签名。- https://github.com/bumptech/glide/issues/2841

我不明白如何做到这一点。

我还尝试了Async任务完全删除缓存。它可以工作,但又很慢(而Glide不建议使用这种方法)。

我不知道如何仅插入当前签名(应该更快),而不是每次加载图像时都创建一个新签名。帮帮我?似乎替换图像并重新缓存它不应该那么困难!

2个回答

4

我花了好几天时间来做这个。

我知道你可能以前看过这个并忽略了,因为你觉得修改你的代码可能需要很多工作。但说实话,它绝对是值得的。就我所知,就性能而言,它超过了所有其他方法的表现,也是Glide推荐的解决方案,并且您不需要跳过缓存或创建签名,因此还可以保持代码更加清洁。

来自Glide:

实际上,当内容发生变化(url、uri、文件路径等)时,使缓存文件失效的最佳方式是更改您的标识符(如果可能)。- https://bumptech.github.io/glide/doc/caching.html

解决方案: 当用户上传新图片时,更改图片的名称。例如获取文件名并使用它。一旦图像URL发生更改,Glide就会理解您已经更改了图像,并相应地更新缓存。迄今为止,这给了我最好的性能。

使用时注意:

.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)

它从不缓存图像,这会导致图像加载缓慢。你可能认为签名对性能更好,我也成功地实现了它们。但对我来说,它们似乎和完全跳过缓存一样慢。


0

两个选项

1)要为文件生成唯一的签名,您可以计算其MD5签名。除非文件被修改,否则它将始终是唯一的。请参阅如何生成MD5签名此处

2)设置唯一签名的另一种方法可能是使用文件的最后修改时间。如果您确定只有您的应用程序会修改图像,而没有其他操作,则也可以依赖此方法。要获取最后修改时间,请使用:

File file = new File("path/to/image");
String signature = Long.toString(file.lastModified());

1
好的,我成功设置了签名并替换了图像。但是当我在其他地方加载该图像时,为什么它仍然显示旧的缓存图像?我需要每次传递新的签名吗?这似乎完全不合逻辑。 - The Fluffy T Rex
@TheFluffyTRex 你找到任何解决方案了吗? - The one

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接