I am new to Android development. My app has use case where I want to download and display images from Internet. I am using Kotlin to build App and decided to use Coil library as Image loading library. While using my application, user's action my trigger download of multiple images. How do these image loading libraries make sure that memory/cache/disk space doesn't fill up? Do these libraries clear/delete images that were downloaded during last use?
The answer is going to depend on the particular library. But in general, they download the images to a file, to serve as a disk cache. That disk cache generally is kept to some limit in terms of size, with files being deleted on an LRU (least recently used) basis. They may then do the same with in memory representations, keeping the last N megabytes worth of images cached in a pool, ejecting on an LRU basis when needed. Ejecting them from the cache may or may not remove them from memory entirely- it depends on if any other reference to the object is maintained by client code. Some libraries allow configurable behavior on this, by either allowing client code to set size limits or provide entire cache implementations.
It's still possible for space to fill up. Especially memory- if you have too many bitmaps open and use up all available heap, then you're going OOM no matter what the loading library does. What the loading library will do is prevent multiple network requests for the same image, and prevent you from having to do all the cache management by hand.
I have a scenario where i have to keep few images in offline mode. Now i am confused here that should i rely on Glide's cache or I have to put those images in Internal Storage?
Hopefully Glide will work, but need to know if there exists any limitation if i go with Glide. Here word cache is causing confusion.
Here is the information about underlying memory usage by Glide.
Glide uses DiskLruCacheWrapper as the default DiskCache. DiskLruCacheWrapper is a fixed size disk cache with LRU eviction. The default disk cache size is 250 MB and is placed in a specific directory in the Application’s cache folder.
Further underlying complexities of Glide are here. Hope confusion about the max memory Glide uses is cleared here and if customization is needed, that can also be achieved by following the link mentioned.
I have this aplication thats keeps building cache every time I open the app
In my app I load like 20 images from my website, but I don't save them to cache,
does the app automatically save this images to cache? If so, I don't think they load from cache, cuz I still have to have internet to load them
Admob in the other hand, if I don't have internet and I loaded the test ad before, it will load the testad.
currently I have the app to delete the cache everytime it starts, keeping cache low, but this doesn't seems smart.
My questions are:
Does admob uses cache of my app?
Knowing my app loads 20 images from my website, this images being
loaded affects my cache size even if I don't save them
programmatically to cache ?
is deleting cache expensive enough to have a dedicated thread to
do just that?
Does admob uses cache of my app?
Yes i think Admob caches its ads so they load faster. And Admob should be managing its own cache size. I don't think you need to worry about that.
Knowing my app loads 20 images from my website, this images being loaded affects my cache size even if I don't save them
programmatically to cache ?
No images or bitmaps will not be cached unless you do so, see this link for more info. I will recommend that you use the Glide or Picasso for image loading since they are memory efficient and abstract out most of the complexity.
Is deleting cache expensive enough to have a dedicated thread to do just that?
I don't think you should use dedicated thread. What you can do is override onTrimMemory and keep monitoring the memory level.When your memory level is critical or low you can delete the cache. Check this link for more info. In my opinion if you use Glide for loading your images it will already handle the memory very well and prevents OutOfMemoryError. Also, loads image much faster.
I'm creating an Android app. For this I created a recyclerview, which gets filled by images and texts. Until now I've got the images from my server with sockets and byte[]. In my app I converted this to bitmaps. But that has not the best performance. Should I get the images with Picasso and URL? Has this a better performance?
Generally in the android or iOS app from the API's we have to get the image url. By using image loader library's we will load that data.
For the android most of the developers prefer universal image loader or picasso for loading their images.
It is best to rely on image loader library like Picasso or UniversalIL as these libraries will manage caching, downsampling and even error handling. Android is very sensitive about bitmap. Without proper management, there will be a lot of exception including the infamous one: BitmapOutOfMemory.
There are 3 locations where images are stored. Their comparison on Memory space availability and Accessibility speed is given below:
Server (Memory Space is HIGH but Accessibility is SLOW)
Hard Disk on Mobile (Memory Space is MEDIUM and Accessibility is MEDIUM)
Heap Memory (Memory Space is LOW and Accessibility is FAST)
We need to create a balance among above 3 locations for optimum utilization of accessibility and memory space.
Use any lazy loading library like picasso or UIL and you don't have to worry about any of these points.It will handle everything itself :)
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)
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.
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.
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.