3

Users can change a picture (replace it). Once the user changes their image, I want the new image to get cached in Glide and the old image to get thrown out of the cache.

I've read everything online but I'm still at a loss on how to implement a good solution to this.

I've tried skipping the local memory and disk caches like when setting the image:

GlideApp.with(fragment)
  .load(url)
  .diskCacheStrategy(DiskCacheStrategy.NONE)
  .skipMemoryCache(true)
  .into(view);

This solution is SLOW because it now calls the new image every single time - it never caches the new image.

Glide documentation says:

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://github.com/bumptech/glide/wiki/Caching-and-Cache-Invalidation

But that is not possible for me, so Glide documentation then says:

Since it’s often difficult or impossible to change identifiers, Glide also offers the signature() API to mix in additional data that you control into your cache key.

And it gives this example:

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

But here comes the issue. What would be a good "yourVersionMetadata"? How do I create and maintain it? I've seen examples like so:

.signature(new ObjectKey(Long.toString(System.currentTimeMillis())))

This causes the disk cache key to change every time I load the image, so it is SLOW. I just need it to change when the user replaces the image. Not every time the image loads.

Someone wrote:

You can do something like generate a new UUID or increment an integer whenever the image changes. If you go that route, you'll have to keep track of the current signature for each image somewhere. - https://github.com/bumptech/glide/issues/2841

I don't understand how to do this.

I also tried the Async task for completely deleting cache. It works, but again it's super slow (and Glide doesn't recommend using this approach).

I don't know how I can just insert the current signature (which should be faster) rather than creating a new signature every time the image loads. Help? It seems to replace an image and recaching it shouldn't be so difficult!

Zoe
  • 27,060
  • 21
  • 118
  • 148
The Fluffy T Rex
  • 430
  • 7
  • 22

2 Answers2

3

I worked on this for days.

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, and I successfully implemented them too. But to me, they seemed just as slow as skipping cache entirely.

The Fluffy T Rex
  • 430
  • 7
  • 22
0

Two options

1) To generate a unique signature for a file you can calculate the MD5 signature for it. It will always be unique for a file until it is modified. See how to generate the MD5 signature here.

2) Another way to set a unique signature could be using the last modified time of the file. If you are sure that only your app will be modifying the image and nothing else then you can also rely on this. To get the last modified time use:

File file = new File("path/to/image");
String signature = Long.toString(file.lastModified());
k1slay
  • 1,068
  • 1
  • 10
  • 18
  • 1
    Ok, so I manage to set the signature and when I replace the image. How come it still shows the old cached image when I load that image elsewhere? Do I need to pass in the new signature each time? That doesn't seem logical at all – The Fluffy T Rex May 05 '20 at 08:30
  • @TheFluffyTRex You found any solution? – The one Jan 26 '22 at 16:11