Universal Image Loader: Can I use cache but also refresh it?
Asked Answered
G

3

8

I'm loading dynamically generated images so I always want them to be up to date. But they take time to load so I also want to display a cached version while the updated one doesn't come. How can I do this with Universal Image Loader?

More specifically, when I call "displayImage" I want it to do the following:

  1. If a cached image exists display it right away.
  2. Start downloading from the given url anyways.
  3. When the image loading finishes, display it in the view replacing the cached image.
  4. Update the cache.
Grati answered 27/9, 2013 at 15:10 Comment(0)
G
26

So in the end I used an ImageLoadingListener as follows:

onLoadingStarted: Check for cache when loading starts.

onLoadingComplete: If no cache was found then do nothing. The request will be sent to network and cache will be updated naturally. Otherwise clear cache and call displayImage again (no listener needed this time). The cached image will be shown in the view normally. Moreover, when the 2nd loading finishes, view and cache will be updated.

ImageLoader.getInstance().displayImage(imageUri, view, new SimpleImageLoadingListener() {
            boolean cacheFound;

            @Override
            public void onLoadingStarted(String url, View view) {
                List<String> memCache = MemoryCacheUtils.findCacheKeysForImageUri(url, ImageLoader.getInstance().getMemoryCache());
                cacheFound = !memCache.isEmpty();
                if (!cacheFound) {
                    File discCache = DiscCacheUtils.findInCache(url, ImageLoader.getInstance().getDiscCache());
                    if (discCache != null) {
                        cacheFound = discCache.exists();
                    }
                }
            }

            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                if (cacheFound) {
                    MemoryCacheUtils.removeFromCache(imageUri, ImageLoader.getInstance().getMemoryCache());
                    DiscCacheUtils.removeFromCache(imageUri, ImageLoader.getInstance().getDiscCache());    
                    ImageLoader.getInstance().displayImage(imageUri, (ImageView) view);
                }
            }
        });
    }
Grati answered 15/10, 2013 at 16:18 Comment(3)
I think the ImageLoader will take care of cache by itself. Am I right?Lashawnda
afaik you can't explicitly make it refresh the cache. whether it refreshes cache after some expiration time I'm not sure but I suppose notGrati
Use DiskCacheUtils instead of DiscCacheUtils in case of compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'Goodish
U
1

You can use the ImageLoadingListener. This interface has 4 methods to override: onLoadingStarted,onLoadingFailed,onLoadingComplete,onLoadingCancelled. In onLoadingStarted you can make the image the cached one, then on completed you change it.

So the call would look like this:

imgLoader.displayImage(url, myImageView,new ImageLoadingListener() 
{

        @Override
        public void onLoadingStarted(String arg0, View arg1) {
            //Display cached image if it exists

        }

        @Override
        public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onLoadingComplete(String arg0, View arg1, Bitmap arg2)
        {

            ((ImageView)arg1).setBitmapImage(arg2);
        }

        @Override
        public void onLoadingCancelled(String arg0, View arg1) {
            // TODO Auto-generated method stub

        }
});
Utrillo answered 27/9, 2013 at 16:10 Comment(1)
Won't it NOT request the image from the network if there's a cache hit? So that the Bitmap I receive in onLoadingComplete is actually the cached one?Grati
F
0
private lateinit var options: DisplayImageOptions

options = DisplayImageOptions.Builder()

                .considerExifParams(true)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .cacheOnDisk(true)
                .cacheInMemory(true)
                .build()   

ImageLoader.getInstance().displayImage(Model.img_url, itemView.ivPlayer, options)
Fidele answered 26/12, 2018 at 9:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.