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

与世无争的帅哥 提交于 2019-11-26 12:40:47

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:

  • 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:

  • 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.

LOG_TAG

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 then.

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 DiskLruCache.

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.

Samuel L

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!