31

Scenario:

I have a large GIF image which I want to cache the first time user opens the app using Glide - Image Loading and Caching library. After that whenever user opens the app, I want to show the cached version if present. This GIF URL will expire after a given interval. When it expires, I fetch the new GIF URL and display/cache that for future use.

What I tried:

I went through 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 question.

From the links above I see the following code sniplet which shows how to load the image from cache. However this only tries to get the image from cache. If its not present in cache, it doesn't try to get from the network and fails:

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

Questions:

  1. Is there a cleaner way to achieve the following: Show the GIF image from the cache if present else download the GIF, cache it for later use and show it in the ImageView.

  2. The caching article above mentions the following:

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

    The server sends a different URL to the app when the previous one expires. In this case, I believe the old image will eventually be Garbage Collected? Is there a way to force remove the image from the cache?

  3. On a similar note, is there a way to prevent the Garbage Collection of an image with specific key (to prevent downloading the large file again) and then later instruct to delete the old image from cache when the URL changes?

Community
  • 1
  • 1
Shobhit Puri
  • 24,785
  • 8
  • 89
  • 115

2 Answers2

39
  1. You don't need a custom ModelLoader to show the GIF from cache if present and fetch it otherwise, that's actually Glide's default behavior. Just using a standard load line should work fine:

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

Your code will prevent Glide from downloading the GIF and will only show the GIF if it is already cached, which it sounds like you don't want.

  1. Yes, the old image will eventually be removed. By default Glide uses an LRU cache, so when the cache is full, the least recently used image will be removed. You can easily customize the size of the cache to help this along if you want. See the Configuration wiki page for how to change the cache size.

  2. Unfortunately there isn't any way to influence the contents of the cache directly. You cannot either remove an item explicitly, or force one to be kept. In practice with an appropriate disk cache size you usually don't need to worry about doing either. If you display your image often enough, it won't be evicted. If you try to cache additional items and run out of space in the cache, older items will be evicted automatically to make space.

Sam Judd
  • 7,017
  • 1
  • 33
  • 37
  • Thanks so much for taking time to answer. Actually that does clear lots of thing. For your first point that's something I want to do. I just wasn't sure if it was the default behaviour. However what made me think that the standard code isn't using the cached image was that when this code executes for first time, I assume Glide caches the image. Now I close the app and switch off the internet. Now when I open the app, the image doesn't show when device is offline. However when I use `StreamModelLoader` as mentioned in the question, it does display it? I appreciate your help. – Shobhit Puri Sep 09 '15 at 15:47
  • I think you were right. Now sure why it was not happening before. Thanks again – Shobhit Puri Sep 10 '15 at 15:31
  • 1
    Glad it worked out, if you do see the behavior where you need that custom ModelLoader to get it to load the GIF offline, please open an issue on GitHub (https://github.com/bumptech/glide/issues/new) so we can look into it, it definitely shouldn't be necessary. – Sam Judd Sep 10 '15 at 15:57
  • @Sam Judd Is it possible that copying cached image to my device folder from Glide's cache memory/folder ? – Karthikeyan Ve May 24 '16 at 15:20
  • @SamJudd Just a question: if I'm showing marks in a google maps using Glide is there any problem if I create a WeakReference to mark's drawable downloaded with Glide?. Because I know already the imagen is in memory and I just wanna change the mark's color when someone touch a mark. – MiguelHincapieC Jan 15 '17 at 00:07
  • Can you help? https://stackoverflow.com/questions/62624070/how-to-priorly-get-future-glide-image-size-which-will-be-stored-in-cache-in-andr – Priyanka Singh Jun 28 '20 at 17:05
2
 Glide.with(context)
 .load("http://sampleurl.com/sample.gif")
 .skipMemoryCache(true)
 .into(imageView);

You already noticed that we called .skipMemoryCache(true) to specifically tell Glide to skip the memory cache. This means that Glide will not put the image in the memory cache. It's important to understand, that this only affects the memory cache! Glide will still utilize the disk cache to avoid another network request for the next request to the same image URL.for more read this Glide Cache & request optimization.

Happy coding!!

Hemant Parmar
  • 3,552
  • 7
  • 22
  • 45