When developing applications for Android, one often faces the problem of displaying some graphical content from the Internet. So, you should provide image loading from the Web in an Android app, their processing and displaying with limited memory again and again. And despite the problem homogeneity, each new project imposes its own specific requirements on the task.
You may need to organize caching of downloaded images; if images are rather large, it is necessary to ensure effective working with the memory to prevent the disastrous mistake OutOfMemoryError . It is also possible that an image-stub has to be showed during the image loading; and maybe the same image should be displayed in different size variations, etc.
As a result, time and resources are wasted for code adaptation to specific needs. It is this problem what urged me on creating a library with open source code - Universal Image Loader for image loading in an Android app. Its aim is solution universalization of the above described problem in a flexible and configurable tool.
Currently, the library can be used everywhere, where you have to download and display (and possibly even to cache) an image from the Internet or from the file system of your smartphone. Classic examples for possibility of ImageLoader using are various lists, tables, galleries, where you need to display images from the Web.
The main features of the ImageLoader for Android are:
- asynchronous loading and displaying images from the Internet or the SD-card;
- ability of caching loaded images in memory and / or the device's file system;
- ability to monitor the loading process by means of "listeners";
- effective working with the memory while caching images in the memory;
- wide opportunities to customize the tool to fit it to your needs.
What can be configured in the ImageLoader?
- the maximum size of images cached in the memory;
- timeout for connection establishing and image loading;
- the maximum number of simultaneously working threads for images loading;
- threads priority during downloading and displaying images;
- implementation of disk cache (you can choose from ready-made implementations or create your own);
- implementation of cache in the memory (you can choose from ready-made implementations or create your own);
- default options of image downloading
Image loading options (applied to each individual call ImageLoader.displayImage(...)) provide the ability to specify:
- whether to display the image-stub in the ImageView, while the real image is being loaded (if yes, then you need to specify this "stub");
- Whether to cache the downloaded image in the memory.
- Whether to cache the downloaded image in the file system.
- Type of image decoding (the fastest or the most economical for the memory).
As already mentioned, you can implement your own version of the disk cache and the cache in memory. But most likely, you will be quite satisfied with ready solutions, most of which are caches, limited by some parameter (size, number of files) and having their own logic of self-cleaning by limit excess (FIFO, the oldest object, the largest object, the most seldom used).
There are enough configuration options, but this is not the case as "the main principle of UNIX": "You can configure EVERYTHING. And you WILL configure everything." :) In the ImageLoader case, you can customize everything, but it is not necessary at all: the default configuration is always available and suitable in the most cases.
Few words about the project structure. Each task for image loading and displaying (and that is, looking ahead, the call ImageLoader.displayImage (imageView, imageUrl)) is performed in a separate thread, except if the picture is in cache in the memory - then it is just immediately displayed. There is a separate threads queue where tasks get if the needed image is cached on the file system. If you do not have the right image in the cache, then the task-thread gets in the thread pool. Therefore, there are no obstacles for a fast displaying of cached images.
The algorithm of the task processing is simplistically represented on the scheme:
The main actors of the project can relatively be divided:
- the above mentioned queue and pool of threads;
- cache in the memory;
- disk cache;
- Image decoder, which decodes image files into Bitmap objects.
The main class ImageLoader manages it all; the main interaction with the user is performed through it.
In the next part, I will tell you directly about the Universal Image Loader API, as well as give some tips and advice on the use of the library.