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

时间:2015-10-30 19:00:16

标签: android caching android-glide

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

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

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

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

如果我更改位置imagePath处的图像与其他具有相同名称的图像,则Glide会显示第一张图片而不是新图片。

两个查询是:

  1. 是否可以始终从文件中取出图像而不是缓存?这样问题就解决了。

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

18 个答案:

答案 0 :(得分:108)

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

方法1:当图像发生变化时,网址会发生变化

http://192.168.122.1:8080/sony/avContent
{"method": "getContentList",
"params": [{
"uri": "storage:memoryCard1",
"stIdx": 0,
"cnt": 500,
"view": "flat",
"sort": ""}],
"id": 1,
"version": "1.3"}

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

方法2:当网址未发生变化时,图片更改

如果您的网址保持不变,则需要使用签名进行图片缓存。

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

Glide signature()使您能够将其他数据与缓存键混合使用。

  • 如果您要从媒体商店获取内容,则可以使用Glide.with(yourFragment) .load(yourFileDataModel) .signature(new StringSignature(yourVersionMetadata)) .into(yourImageView); MediaStoreSignature允许您将日期修改时间,mime类型和媒体商店项目的方向混合到缓存键中。这三个属性可靠地捕获编辑和更新,允许您缓存媒体商店的大拇指。
  • 对于保存为文件的内容,您也可MediaStoreSignature以混合文件日期修改时间。

答案 1 :(得分:46)

正如Glide wiki的Caching and Cache Invalidation部分所述:

  

因为文件名是散列键,所以没有简单的方法   删除磁盘上与特定对应的所有缓存文件   网址或文件路径。如果你只是永远,问题会更简单   允许加载或缓存原始图像,但由于Glide也   缓存缩略图并提供各种变换,每个变换   将导致缓存中的新文件,跟踪和删除   每个图像的缓存版本都很难。

     

实际上,使缓存文件无效的最佳方法是在内容更改时更改您的>标识符(网址,文件路径等)。

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

如果您想每次从磁盘重新加载图像,可以像这样更改代码:

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

答案 2 :(得分:25)

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

public static final int HAUTE_IMPORTANCE = 1;
public static final int MOYENNE_IMPORTANCE = 2;
public static final int FAIBLE_IMPORTANCE = 3;


private static int dernierIdAttribue = 0; 


private Date dateCreation = Date.dateDuJour();
private Date dateLimite; 
private String description;
private int niveauImportance;
private boolean acheve;
private int id;

public Todo (String description, Date dateLimite) throws TodoInvalideException{

    if ( dateLimite == null||dateCreation.estEgale(dateLimite) ||!dateCreation.estPlusRecente(dateLimite) && description != null && !description.isEmpty()){
    this.description = description;                      
    this.dateLimite = null;
    this.niveauImportance = FAIBLE_IMPORTANCE;
    acheve = false;
    dernierIdAttribue++;
    id = dernierIdAttribue;            

    } else{
        throw new TodoInvalideException("Erreur constructeur2");  

答案 3 :(得分:20)

有两种方法可以处理 Glide 缓存刷新

第一道: - 在下面添加滑行实施

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

第二种方式:

如果您能够识别图像更改,请在下面提供新文件名

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

或者您希望每次都使用最新图片加载,请使用下面的

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

希望这有帮助。

答案 4 :(得分:15)

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

我正在使用这样的头像图像惯例,我将其下载到Glide以外的File个对象,然后使用Glide来有效地调整大小并使它们成为圆形等等。

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

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

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

答案 5 :(得分:15)

Glide 4.2.0遇到麻烦,StringSignature未解决。

看起来StringSignature已不再可用,您必须使用ObjectKey

所以代码看起来像

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

答案 6 :(得分:11)

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

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

答案 7 :(得分:9)

在最新版本中,我们应该使用RequestOptions

RequestOptions 提供与类型无关的选项,以便在最新版本的Glide中使用Glide自定义负载。

创建一个RequestOptions对象,并在我们加载图像时使用它。

 RequestOptions requestOptions = new RequestOptions()
                        .diskCacheStrategy(DiskCacheStrategy.NONE) // because file name is always same
                        .skipMemoryCache(true);

 Glide.with(this)
           .load(photoUrl)
           .apply(requestOptions)
           .into(profile_image);

答案 8 :(得分:9)

我使用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)

我希望它会帮助某人

答案 9 :(得分:5)

使用GlideApp签名

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

答案 10 :(得分:4)

这对我有用

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

答案 11 :(得分:4)

最后是Kotlin的实现(对于片段):

Glide.with(activity)
            .load(url)
            .apply(RequestOptions()
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .skipMemoryCache(true))
            .into(myImageView)

答案 12 :(得分:3)

我做了几天的工作,所有上述解决方案都只是懒惰而已。

我知道您以前可能已经读过这篇文章并忽略了它,因为您认为更改代码可能需要大量工作。但是说真的,这是值得的。据我所知,它的性能超过了所有其他介绍的方法,这是Glide推荐的解决方案,并且您无需跳过缓存或创建签名,因此也可以使代码更整洁。

FROM滑行:

实际上,使缓存文件无效的最佳方法是更改您的 内容更改时的标识符(URL,URI,文件路径等)何时 可能。 -https://bumptech.github.io/glide/doc/caching.html

解决方案: 用户上载新图像时,请更改图像名称。获取文件名并使用它作为示例。图像URL更改后,Glide将了解您已更改图像,并将相应地更新缓存。 到目前为止,这给了我最好的表现。

使用时:

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

它从不缓存图像,这确实使图像加载缓慢。您可能会认为签名在性能上更好,但是对我来说它们似乎同样慢。

答案 13 :(得分:2)

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

您所要做的就是将与图像文件相关的信息设置为签名。当您替换该文件时,信息也会发生变化,Glide知道必须重新加载它,忽略缓存。

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

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

Here我找到了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();
   }
}

答案 14 :(得分:2)

这个对我有用!

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

答案 15 :(得分:1)

我正在使用Glide加载File,这是我的最终工作,以确保每次文件更改时Glide的磁盘缓存都会失效(即使它具有相同的路径):

Glide.with(context)
    .load(bitmapFile)
    .signature(new ObjectKey(bitmapFile.lastModified()))
    .into(imageView);

答案 16 :(得分:0)

Programmatically simply you can use,

 Glide.get(getApplicationContext()).clearMemory();
 Glide.get(getApplicationContext()).clearDiskCache();

For More

答案 17 :(得分:0)

1)首先清除磁盘缓存。

private class ClearGlideCacheAsyncTask extends AsyncTask<Void, Void, Boolean>{

        private boolean result;

        @Override
        protected Boolean doInBackground(Void... params) {
            try {
                Glide.get(getContext()).clearDiskCache();
                result = true;
            }
            catch (Exception e){
            }
            return result;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if(result)
                Toast.makeText(getActivity(), "cache deleted", Toast.LENGTH_SHORT).show();
        }
    }

您可以使用new ClearGlideCacheAsyncTask ().execute();从您的用户界面拨打电话

2)清除内存缓存

// This method must be called on the main thread.
Glide.get(context).clearMemory();

来源:https://bumptech.github.io/glide/doc/caching.html