Home » Android » Local image caching solution for Android: Square Picasso, Universal Image Loader, Glide, Fresco?

Local image caching solution for Android: Square Picasso, Universal Image Loader, Glide, Fresco?

Posted by: admin March 11, 2020 Leave a comment


I am looking for an asynchronous image loading and caching library in Android. I was going to use Picasso, but I found Universal Image Loader is more popular on GitHub. Does anyone know about these two libraries? A summary of pros and cons would be great.

(All my images are on disk locally, so I don’t need networking, therefore I don’t think Volley is a fit)

How to&Answers:

Update Sep 2018: After several years, I needed the almost same thing for a local image caching solution. This time around, UIL has not been in active development. I compared the popular libraries, and the conclusion is pretty no-brainer: just use Glide. It’s much more powerful and configurable. Years ago I had to fork and make changes to UIL. Glide supports all my use cases in terms of caching strategy and multiple levels of resolution caching with custom keys. Just use Glide!

Koushik Dutta’s comparison is mostly for speed benchmark. His post only touched very basic things, and is not specific for local images. I’d like to share my experiences with Picasso and UIL after I asked the question. Both Picasso and UIL can load local images. I first tried Picasso and was happy, but later I decided to switch to UIL for more customization options.


  • Picasso’s fluent interface is nice. But jumping around with “with”, “into”, “load” you actually don’t know what’s behind the scene. It’s confusing what’s returned.

  • Picasso allows you to specify exact target size. It’s useful when you have memory pressure or performance issues, you can trade off some image quality for speed.

  • Images are cached with size in its key, it’s useful when you display images with different sizes.

  • You can customize the memory cache size. But its disc cache is only for http requests. For local images, if you care about loading speed, it’s good to have a thumbnail disk cache so you don’t have to read several MBs for an image every time. Picasso does not have this mechanism resizing and saving thumbnails on disk.

  • Picasso does not expose the access to its cache instance. (You can get a hold of it when you first configure Picasso and keep it around…).

  • Sometimes you want to asynchronously read image into a bitmap returned by a listener. Surprisingly Picasso doesn’t have that. “fetch()” dose not pass back anything. “get()” is for synchronously read, and “load()” is for asynchronously draw a view.

  • Picasso only has a few simple examples on the homepage, and you’ll have to read through the unordered javadoc for advanced usages.


  • UIL uses builders for customization. Almost everything can be configured.

  • UIL does not allow you to specify the size you want to load into a view. It uses some rules based on the size of the view. It’s not as flexible as Picasso. I have no way to load a lower resolution image to reduce memory footprint. (Edit: this behavior can be easily modified by adding an ImageSize argument in in the source code and bypass the view size checking)

  • UIL provides customizable disc cache, you can use this to cache the thumbnails with specified size. But it’s not perfect. Here are the details. (Edit: if you care about speed and want multiple levels of thumbnail caching, like my case, you can modify the source code, let the disk cache use “memoryKey”, and make it also size sensitive)

  • UIL by default caches images of different sizes in memory, and it can be turned off in configuration.

  • UIL exposes the backing memory and disk cache you can access.

  • UIL provides flexible ways you can get a bitmap or load to a view.

  • UIL is better in documentation. UIL gives the detailed usages on the Github page, and there’s a linked tutorial.

I suggest starting with Picasso, if you need more control and customization, go for UIL.


If you read this post on G+ by Koush you will get clear solutions for your confusions, I have put the summary of that, in that Android-Universal-Image-Loader is the winner for your requirement!

  • Picasso has the nicest image API if you are using network!

  • UrlImageViewHelper + AndroidAsync is the fastest. Playing with these
    other two great libraries have really highlighted that the image API
    is quite dated, however.

  • Volley is slick; I really enjoy their pluggable backend transports,
    and may end up dropping AndroidAsync in there. The request priority
    and cancellation management is great(if you are using network)

  • Android-Universal-Image-Loader is the most popular one out there
    currently. Highly customizable.

This project aims to provide a reusable instrument for asynchronous
image loading, caching and displaying. It is originally based on Fedor
Vlasov’s project and has been vastly refactored and improved since

Upcoming changes in new UIL version (1.9.2):

Possibility to call ImageLoader out of UI threadNew Disk Cache API
(more flexible). New LruDiscCache based on Jake Wharton’s

Considering all this Android-Universal-Image-Loader suites your requirement (Loading the images are on disk locally)!


I would like to share my experience with these 3 libraries: UIL, Picasso and Volley. I previously used UIL but then I came to the conclusion I can’t really recommend it and I would suggest to use Volley or Picasso instead which are both developed by highly talented teams. UIL is not bad at all but it lacks the attention to detail of the other two libraries.

I found UIL being less nice with the UI performance; it tends to lock up the UI thread more than Volley or Picasso. This may be in part due to the fact that UIL does not support batching the image responses while Picasso and Volley do that by default.

Also, I didn’t like the disk cache system of UIL. While you can choose between various implementations, I need to point out that at the moment there is no way to limit the UIL disk cache both by total size and by entity expiration time. Volley and Picasso do that, and they use the expiration time returned by the server by default while UIL ignores it.

Finally, UIL allows you to set a global image loader configuration which includes the selected disk cache and memory cache implementations and settings and other details, but this configuration will be applied everywhere in your app. So if you need more flexibility like two separate disk caches, it’s a no go for UIL. Volley on the other hand allows you to have as many separate image loaders as you want, each with its own configuration. Picasso uses a global instance by default but also allows you to build separately configurable instances.

To sum it up: Picasso has the best API but it uses the global HTTP disk cache shared between all HttpURLConnection instances, which can be too restrictive in some cases. Volley has the best performance and modularity but is less user friendly and will require that you write a module or two of your own to make it work like you want. Overall I would recommend them both against UIL.

Edit (Dec 18 2014): Things have changed since I wrote this initial answer and I felt it was necessary to improve it:

Picasso 2.4 is even more configurable than older releases, and when used with OkHttp (which is highly recommended) it is also able to use a separate disk cache for each instance so there is really no restriction in what you can do.
More importantly, I noticed that the performance of Picasso and OkHttp has improved a lot and in my opinion it’s now the fastest image loader solution for Android, period. Please note that in my code I always use .fit() in combination with .centerCrop() or .centerInside() to lower memory usage and avoid bitmap resizes on the UI thread. Picasso is actively developed and supported and that’s certainly a big plus.

Volley hasn’t changed that much but I noticed two issues with it in the meantime:

  • Sometimes under heavy load, some images are not loaded any more because of some disk cache corruption.
  • Thumbnails displayed in a NetworkImageView (with its scale type set to centerCrop) are quite blurry compared to what you get with the other libraries.

For these reasons I decided to stop using Volley.

UIL is still slow (especially the disk cache) and its API has a tendency to change quite often.

I also tested this new library called Glide 3 which claims to be more optimized than Picasso with a Picasso-like API. According to my personal experience it’s actually slower than Picasso and Volley during network requests under heavy load, even when used in combination with OkHttp. Worse, it caused a few crashes with my apps under Lollipop when leaving an activity. It still has 2 advantages over its competitors:

  • It supports animated GIFs decoding
  • It puts the final downscaled bitmaps in the disk cache, which means reading back from the disk cache is extremely fast.

Conclusion: I now recommend to use Picasso + OkHttp because it provides the best flexibility, API, performance and stability combined. If you need GIF support you can also consider Glide.


I have implemented an app that should constantly get and show images from the internet. I was about to program an image cache mechanism, before that a friend recommended me the universal image loader.

The UIL is very good customizable. It’s so customizable that a newbie can easily make something wrong. However, the UIL was slow in my application and it became a bit slower. My use case was a ListView with images.

Yesterday I was looking for an alternative to the UIL, and I discovered Picasso. Picasso was easy to integrate and to use: Just Picasso.context(context).load(url).into(imageview) and the image could be faster and smoothly be integrated.

For me, Picasso is definitely the API to use. My experience with UIL wasn’t good.


I think ImageLoader is more customizable and flexible comparing to Picasso library.