Remove image from cache in Glide library

AndroidCachingAndroid Glide

Android Problem Overview


I am using Glide in one of my projects to show image from file.

Below is my code how I am showing the image:

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

The image at this location(imagePath) keeps on changing. By default Glide cache the image it shows in the ImageView. Because of this, the Glide was showing the first image from cache for new images at that location.

If I change the image at location imagePath with some other image having same name then the Glide is showing the first image instead of new one.

Two queries are:

  1. Is it possible to always the image from File and not cache? This way problem will be solved.

  2. Is it possible to clear image from cache before getting newly replaced image? This will also solve the problem.

Android Solutions


Solution 1 - Android

This is how I solved this problem.

Method 1: When the URL changes whenever image changes

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

diskCacheStrategy() can be used to handle the disk cache and you can skip the memory cache using skipMemoryCache() method.

Method 2: When URL doesn't change, however, image changes

If your URL remains constant then you need to use Signature for image cache.

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

Glide signature() offers you the capability to mix additional data with the cache key.

  • You can use MediaStoreSignature if you are fetching content from media store. MediaStoreSignature allows you to mix the date modified time, mime type, and orientation of a media store item into the cache key. These three attributes reliably catch edits and updates allowing you to cache media store thumbs.
  • You may StringSignature as well for content saved as Files to mix the file date modified time.

Solution 2 - Android

As explained in the section Caching and Cache Invalidation of the Glide wiki:

> Because File names are hashed keys, there is no good way to simply > delete all of the cached files on disk that correspond to a particular > url or file path. The problem would be simpler if you were only ever > allowed to load or cache the original image, but since Glide also > caches thumbnails and provides various transformations, each of which > will result in a new File in the cache, tracking down and deleting > every cached version of an image is difficult. > >In practice, the best way to invalidate a cache file is to change your >identifier when the content changes (url, uri, file path etc).

Since you can't change the file path, Glide offers the signature() API that allows you sets some additional data to be mixed in to the memory and disk cache keys allowing the caller more control over when cached data is invalidated.

If you want to reload every time the image from the disk, you can change your code like this:

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

Solution 3 - Android

There are two ways to handle Glide cache refresh,

Firstway: - Add below with glide implementation

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

Second way:

If you able to identify image changes then give your new file name in below,

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

or you want to load every time with latest images , use below

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

Hope this helps.

Solution 4 - Android

This will remove cache memory which is stored by Glide.And it should be done in background otherwise it will throw exception

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

Solution 5 - Android

Had troubles with Glide 4.2.0, StringSignature was not resolved.

Looks like StringSignature is not available anymore and you have to use ObjectKey instead.

So code looks like

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

Solution 6 - Android

If you save images to the same known filename as a convention and want to invalidate the Glide cache only when the file has changed, using the file modification timestamp can work well.

I was using such a convention for avatar images which I was downloading to File objects outside Glide, and then using Glide just to efficiently resize and make them round, etc.

So I ended up using the StringSignature strategy with the value of the file's lastChanged timestamp as the signature. Here's what the fluent code for that looks like:

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

where avatarFile is my java.io.File object, of course.

Solution 7 - Android

I had troubles with setting signature using Glide version 4.* with Kotlin. After some time I ended up with this:

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

It's an extension function for ImageView, and it's used this way:

 imageView.loadUrl(url)

I Hope it will help someone

Solution 8 - Android

For Glide 4.3.+ library you need to something like this to ,

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

Solution 9 - Android

In the latest versions we should use RequestOptions

RequestOptions Provides type independent options to customize loads with Glide in the latest versions of Glide.

Make a RequestOptions Object and use it when we are loading the image.

 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);

Solution 10 - Android

I worked on this for days, and all the above-mentioned solutions are just slow as a sloth.

I know you've probably read this before and ignored it because you thought it would probably take a lot of work to change your code. But seriously, it's well worth it. The performance, as far as I can tell, beats all the other methods presented, it's Glide's recommended solution, AND you don't need to skip cache or create signatures so it keeps your code cleaner too.

FROM Glide:

> In practice, the best way to invalidate a cache file is to change your > identifier when the content changes (url, uri, file path etc) when > possible. - https://bumptech.github.io/glide/doc/caching.html

SOLUTION: Change the name of the image when the user uploads a new image. Get the file name and use that for example. Once the image URL has changed, Glide understands you have changed the image and will update the Cache accordingly. This has by far given me the best performance.

WHEN USING:

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

It never caches the images and this really makes images load slowly. You'd think Signatures are better for performance, but to me they seemed just as slow.

Solution 11 - Android

signature with GlideApp

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

Solution 12 - Android

I was using Glide to load a File, and here's what I ended up doing to make sure Glide's disk cache was invalidated every time my file changed (even though it had the same path):

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

Solution 13 - Android

And finally Kotlin implementation (For Fragments):

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

Solution 14 - Android

This worked for me

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

Solution 15 - Android

Programmatically simply you can use:

 // must run on main thread
 Glide.get(getApplicationContext()).clearMemory(); 

 // must run in background thread
 Glide.get(getApplicationContext()).clearDiskCache(); 

For More

Solution 16 - Android

This one worked for me!

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

Solution 17 - Android

To benefit from the cache provided by Glide and ensure that the correct image is shown everytime, you can use the signature() API.

All you have to do is to set as signature an information that relates to the image file. When you replace that file, the information changes too and Glide knows it must reload it, ignoring the cache.

A valid information could be a digest (for example SHA-1) calculated on the file contents.

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

Here I found the following implementation of sha1() function:

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();
   }
}

Solution 18 - Android

  1. First clear disk cache.

    private class ClearGlideCacheAsyncTask extends AsyncTask{

         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();
         }
     }
    

You can call from your ui with new ClearGlideCacheAsyncTask ().execute();

  1. Clear memory cache

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

Source : https://bumptech.github.io/glide/doc/caching.html

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNitesh KumarView Question on Stackoverflow
Solution 1 - AndroidNitesh KumarView Answer on Stackoverflow
Solution 2 - AndroidMattia MaestriniView Answer on Stackoverflow
Solution 3 - AndroidChandrahasanView Answer on Stackoverflow
Solution 4 - AndroidAnand SavjaniView Answer on Stackoverflow
Solution 5 - AndroidAndrey DanilovView Answer on Stackoverflow
Solution 6 - AndroidDhiraj GuptaView Answer on Stackoverflow
Solution 7 - AndroidPalejandroView Answer on Stackoverflow
Solution 8 - AndroidJaydipsinh ZalaView Answer on Stackoverflow
Solution 9 - AndroidVinay JohnView Answer on Stackoverflow
Solution 10 - AndroidThe Fluffy T RexView Answer on Stackoverflow
Solution 11 - AndroidDan AlboteanuView Answer on Stackoverflow
Solution 12 - AndroidAdam JohnsView Answer on Stackoverflow
Solution 13 - AndroidEugene VoronoyView Answer on Stackoverflow
Solution 14 - AndroidShreyas SanilView Answer on Stackoverflow
Solution 15 - AndroidAsk ShiwaView Answer on Stackoverflow
Solution 16 - AndroidAllan JaqueiraView Answer on Stackoverflow
Solution 17 - AndroidRiccardo LeschiuttaView Answer on Stackoverflow
Solution 18 - AndroidZharView Answer on Stackoverflow