Glide:如何查找图像是否已缓存并使用缓存版本?

Glide : How to find if the image is already cached and use the cached version?

场景

我有一个很大的 GIF 图片,我想在用户第一次使用 Glide - 图像加载和缓存库打开应用程序时缓存它。之后,每当用户打开应用程序时,我想显示缓存版本(如果存在)。此 GIF URL 将在给定时间间隔后过期。当它过期时,我获取新的 GIF URL 和 display/cache 以备将来使用。

我试过的:

我完成了 Caching and Cache Invalidation on Glide's github page. I also went though the Google Group thread Ensuring That Images Loaded Only Come From Disk Cache, which shows how to get the image form cache. I also went through How to invalidate Glide cache for some specific images 个问题。

从上面的链接中,我看到了以下代码片段,它显示了如何从缓存中加载图像。但是,这只会尝试从缓存中获取图像。如果它不在缓存中,它不会尝试从网络获取并失败:

Glide.with(TheActivity.this)
        .using(new StreamModelLoader<String>() {
            @Override
            public DataFetcher<InputStream> getResourceFetcher(final String model, int i, int i1) {
                return new DataFetcher<InputStream>() {
                    @Override
                    public InputStream loadData(Priority priority) throws Exception {
                        throw new IOException();
                    }

                    @Override
                    public void cleanup() {
                    }

                    @Override
                    public String getId() {
                        return model;
                    }

                    @Override
                    public void cancel() {
                    }
                };
            }
        })
       .load("http://sampleurl.com/sample.gif")
       .diskCacheStrategy(DiskCacheStrategy.SOURCE)
       .into(theImageView);

问题:

  1. 是否有更清晰的方法来实现以下目标:如果存在则从缓存中显示 GIF 图像,否则下载 GIF,将其缓存以备后用并在 ImageView 中显示。

  2. 上面的缓存文章提到了以下内容:

    In practice, the best way to invalidate a cache file is to change your identifier when the content changes (url, uri, file path etc)

    服务器在前一个过期时向应用程序发送一个不同的URL。在这种情况下,我相信旧图像最终会被垃圾收集?有没有办法强制从缓存中删除图像?

  3. 在类似的说明中,有没有办法阻止具有特定键的图像的垃圾收集(以防止再次下载大文件)然后指示从缓存中删除旧图像当 URL 改变时?

  1. 您不需要自定义 ModelLoader 来显示缓存中的 GIF(如果存在)或获取它,这实际上是 Glide 的默认行为。只需使用标准负载线就可以正常工作:

    Glide.with(TheActivity.this)
       .load("http://sampleurl.com/sample.gif")
       .diskCacheStrategy(DiskCacheStrategy.SOURCE)
       .into(theImageView);
    

您的代码将阻止 Glide 下载 GIF,并且只会显示已缓存的 GIF,这听起来像是您不想要的。

  1. 是的,旧图像最终会被删除。默认情况下,Glide 使用 LRU 缓存,所以当缓存满时,最近最少使用的图像将被移除。如果需要,您可以轻松自定义缓存的大小来帮助实现这一点。有关如何更改缓存大小的信息,请参阅 Configuration wiki 页面。

  2. 遗憾的是,没有任何方法可以直接影响缓存的内容。您既不能显式删除一项,也不能强制保留一项。在实践中,如果磁盘缓存大小合适,您通常不需要担心这两个问题。如果您经常显示图像,它就不会被驱逐。如果您尝试在缓存中缓存 space 中的其他项目和 运行,较旧的项目将被自动逐出以生成 space。

 Glide.with(context)
 .load("http://sampleurl.com/sample.gif")
 .skipMemoryCache(true)
 .into(imageView);

你已经注意到我们调用了 .skipMemoryCache(true) 专门告诉 Glide 跳过内存缓存。这意味着 Glide 不会将图像放入内存缓存中。重要的是要理解,这只会影响内存缓存! Glide 仍然会利用磁盘缓存来避免对同一图像的下一个请求的另一个网络请求 URL.for 阅读更多 Glide Cache & request optimization.

编码愉快!!