从Glide库中的缓存中删除图像

我在我的一个项目中使用Glide来显示来自文件的图像。

下面是我的代码如何显示图像:

Glide.with(DemoActivity.this) .load(Uri.parse("file://" + imagePath)) .into(mImage); 

这个位置的图像( imagePath )不断变化。 默认情况下,Glide缓存它在ImageView显示的ImageView 。 因此,Glide正在显示缓存中的第一张图像,以显示该位置的新图像。

如果我更改位置imagePath与其他具有相同名称的图像的图像然后Glide显示第一个图像,而不是新的。

两个查询是:

  1. 是否有可能永远从文件的图像,而不是缓存? 这样问题就解决了。

  2. 获取新替换的图像之前是否可以清除缓存中的图像? 这也将解决问题。

这就是我解决这个问题的方法。

方法1:当图像更改时URL更改

 Glide.with(DemoActivity.this) .load(Uri.parse("file://" + imagePath)) .diskCacheStrategy(DiskCacheStrategy.NONE) .skipMemoryCache(true) .into(mImage); 

可以使用diskCacheStrategy()来处理磁盘缓存,并且可以使用skipMemoryCache()方法跳过内存缓存。

方法2:但是,URL不更改时,图像更改

如果您的URL保持不变,那么您需要使用Signature进行图像缓存。

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

Glide签名()提供了将额外数据与缓存键混合的function。

  • 如果您从媒体存储中获取内容,则可以使用MediaStoreSignatureMediaStoreSignature允许您将媒体存储项目的日期修改时间,MIMEtypes和方向混合到缓存键中。 这三个属性可靠地捕捉和更新,让您缓存媒体商店的大拇指。
  • 对于保存为文件的内容,也可以使用StringSignature来混合文件日期修改时间。

正如在Glide wiki的缓存和缓存失效一节中所解释的:

因为文件名是散列键,所以没有办法简单地删除磁盘上对应于特定url或文件路径的所有缓存文件。 如果您只允许加载或缓存原始图像,则问题会更加简单,但由于Glide也会缓存缩略图并提供各种转换,其中每个转换都会导致缓存中的新文件,跟踪并删除每个缓存版本的图像是困难的。

在实践中,使缓存文件无效的最好方法是在内容更改(url,uri,文件路径等)时更改>标识符。

由于您无法更改文件路径,因此Glide提供了signature() API,允许您将一些其他数据混合到内存和磁盘缓存键中,从而允许调用方在缓存的数据失效时更好地进行控制。

如果你想每次从磁盘重新加载镜像,你可以像这样改变你的代码:

 Glide.with(DemoActivity.this) .load(Uri.parse("file://" + imagePath)) .signature(new StringSignature(String.valueOf(System.currentTimeMillis()))) .into(mImage); 

这将删除由Glide存储的缓存。并且它应该在后台完成,否则会抛出exception

 new Thread(new Runnable() { @Override public void run() { Glide.get(MainActivity.this).clearDiskCache(); } }).start(); 

如果将图像保存为与约定相同的已知文件名,并且仅在文件更改时才使Glide缓存无效,则使用文件修改时间戳可以很好地工作。

我正在使用这样的惯例为我下载到Glide之外的File对象的头像图像,然后使用Glide来有效地resize并使它们变圆。

所以我最终使用StringSignature策略和文件的lastChanged时间戳的值作为签名。 以下是流畅的代码:

 Glide.with(this) .load(avatarFile) .diskCacheStrategy(DiskCacheStrategy.RESULT) .signature(new StringSignature(String.valueOf(avatarFile.lastModified()))) .into(ivProfile); } 

当然, avatarFile是我的java.io.File对象。

有两种方法来处理Glide缓存刷新,

Firstway: – 在下面添加glide实现

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

第二种方式:

如果你能够识别图像变化,然后在下面给你新的文件名,

 .signature(new StringSignature(String.valueOf(fileName))) 

或者你想每次加载最新的图像,使用下面

 .signature(new StringSignature(String.valueOf(System.currentTimeMillis()))) 

希望这可以帮助。

使用Glide版本4设置签名时遇到困难。*与Kotlin。 过了一段时间,我结束了这个:

 fun ImageView.loadUrl(url: String) { var requestOptions = RequestOptions() requestOptions.signature(ObjectKey(System.currentTimeMillis())) Glide.with(this).load(url).apply(requestOptions).into(this) } 

这是ImageView的扩展函数,它是这样使用的:

  imageView.loadUrl(url) 

我希望它会帮助别人

有Glide 4.2.0的麻烦, StringSignature没有解决。

看起来像StringSignature不再可用,你必须改用ObjectKey

所以代码看起来像

 Glide.with(imageView). load(pathToImage). apply(new RequestOptions().signature(new ObjectKey("signature string"))). into(imageView); 

这对我有效

  //use diskCacheStrategy(DiskCacheStrategy.NONE) after skipMemoryCache(true) Glide.with(this) .load(image) .skipMemoryCache(true) .diskCacheStrategy(DiskCacheStrategy.NONE) .into(imageview); 

为了从Glide提供的缓存中受益,并确保每次都显示正确的图像,可以使用signature()API 。

所有你需要做的就是把与图像文件相关的信息设置为签名。 当你替换这个文件时,信息也会改变,Glide知道它必须重新加载它,忽略缓存。

有效的信息可以是文件内容计算的摘要(例如SHA-1)。

 Glide.with(context) .load(inputFile) .signature(new StringSignature(sha1(inputFile))) .into(targetImageView); 

在这里我find了以下sha1()函数的实现:

 public static String sha1(final File file) throws NoSuchAlgorithmException, IOException { final MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); try (InputStream is = new BufferedInputStream(new FileInputStream(file)) { final byte[] buffer = new byte[1024]; for (int read = 0; (read = is.read(buffer)) != -1;) { messageDigest.update(buffer, 0, read); } } // Convert the byte to hex format try (Formatter formatter = new Formatter()) { for (final byte b : messageDigest.digest()) { formatter.format("%02x", b); } return formatter.toString(); } } 

对于Glide 4.3。+库你需要这样的东西,

 Glide.with(context) .load(image_path) .apply(new RequestOptions() .diskCacheStrategy(DiskCacheStrategy.NONE) .skipMemoryCache(true)) .into(imge_view); 

签名与GlideApp

  GlideApp.with(imageView) .load(url) .signature(new ObjectKey(System.currentTimeMillis())) .placeholder(R.drawable.sky) .error(R.drawable.sky) .into(imageView);