Nitesh Kumar
Nitesh Kumar

Reputation: 5440

Remove image from cache in Glide library

I am using Glide in one of my projects to show images from files.

Below is my code of 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 the cache for new images at that location.

If I change the image at location imagePath with some other image having the same name then the Glide is showing the first image instead of the 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 the image from the cache before getting the newly replaced image? This will also solve the problem.

Upvotes: 99

Views: 119456

Answers (19)

Nitesh Kumar
Nitesh Kumar

Reputation: 5440

This is how I solved this problem.

Method 1: When the URL changes whenever the 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 the skipMemoryCache() method.

Method 2: When the URL doesn't change, however, the 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 a 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.

Upvotes: 187

Enakhi
Enakhi

Reputation: 1173

you can use a time stamp, that time could be the file's date modified or System.currentTimeMillis()

this works perfectly

Glide.with(DemoActivity.this)
 .load(Uri.parse("file://" + imagePath+"?time="+System.currentTimeMillis()))
 .into(mImage);

Upvotes: 0

Amal
Amal

Reputation: 321

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

Upvotes: 3

The Fluffy T Rex
The Fluffy T Rex

Reputation: 600

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.

Upvotes: 8

Zhar
Zhar

Reputation: 3540

1) First clear disk cache.

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

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

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

Upvotes: 1

Adam Johns
Adam Johns

Reputation: 36373

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

Upvotes: 7

Chandrahasan
Chandrahasan

Reputation: 2079

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.

Upvotes: 48

Vinay John
Vinay John

Reputation: 1029

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

Upvotes: 13

Allan Jaqueira
Allan Jaqueira

Reputation: 27

This one worked for me!

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

Upvotes: 2

Eugene Voronoy
Eugene Voronoy

Reputation: 1433

And finally Kotlin implementation (For Fragments):

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

Upvotes: 5

Jaydipsinh Zala
Jaydipsinh Zala

Reputation: 16798

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

Upvotes: 13

Dan Alboteanu
Dan Alboteanu

Reputation: 10252

signature with GlideApp

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

Upvotes: 6

Andrey Danilov
Andrey Danilov

Reputation: 6602

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

Upvotes: 27

Palejandro
Palejandro

Reputation: 2351

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

Upvotes: 14

Shreyas Sanil
Shreyas Sanil

Reputation: 552

This worked for me

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

Upvotes: 4

Dhiraj Gupta
Dhiraj Gupta

Reputation: 10514

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.

Upvotes: 16

Anand Savjani
Anand Savjani

Reputation: 2535

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

Upvotes: 40

Riccardo Leschiutta
Riccardo Leschiutta

Reputation: 467

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

Upvotes: 1

Mattia Maestrini
Mattia Maestrini

Reputation: 32810

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

Upvotes: 64

Related Questions