Universal Image Loader. Part 2

Sergei Terekhov

Written by Sergei Terekhov Понедельник, 12 Март 2012

All manipulations are held by the ImageLoader class. It is a singletone, so to get a single instance of the class, you should call the getInstance() method. Before using ImageLoader to its intended purpose (to display images), you should initialize its configuration - ImageLoaderConfiguration using the init (...) method. Well, then you can use all variations of the displayImage(...) method with a clear conscience.

In general, the easiest option of using ImageLoader (with the default configuration) is shown below:
ImageView imageView = ... // view, where the image will be displayed
String imageUrl = ... // image URL (e.g. "http://site.com/image.png", "file:///mnt/sdcard/img/image.jpg")
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration .createDefault(context));
imageLoader.displayImage(imageUrl, imageView);

Now, let’s consider the full functionality.
As you already know, you first need to initialize the ImageLoader using the configuration object. As the ImageLoader is a singleton, then it should be initialized only once for application launching. I would recommend doing it in an overloaded Application.onCreate(). A reinitializing of an already initialized ImageLoader will have no effect.
So, we create a configuration, it is an object of the ImageLoaderConfiguration class. We create it using the Builder:

File cacheDir = StorageUtils.getCacheDirectory(context,
"UniversalImageLoader/Cache");

ImageLoaderConfiguration config = new
ImageLoaderConfiguration .Builder(getApplicationContext())
.maxImageWidthForMemoryCache(800)
.maxImageHeightForMemoryCache(480)
.httpConnectTimeout(5000)
.httpReadTimeout(20000)
.threadPoolSize(5)
.threadPriority(Thread.MIN_PRIORITY + 3)
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new UsingFreqLimitedCache(2000000)) // You can pass your own memory cache implementation
.discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
.defaultDisplayImageOptions(DisplayImageOptions.createSimple())
.build();

Let’s consider each option:
• maxImageWidthForMemoryCache() and maxImageHeightForMemoryCache() is used for decoding images into Bitmap objects. In order not to store a full-sized image in the memory, it is reduced to a size determined from the values of ImageView parameters, where the image is loaded: maxWidth and maxHeight (first stage), layout_width and layout_height (second stage). If these parameters are not defined (values fill_parent and wrap_content are considered as uncertain), then dimensions specified by settings maxImageWidthForMemoryCache() and maxImageHeightForMemoryCache() are taken. The size of the original image is reduced by 2 times (recommended for fast decoding), till the width or height becomes less than the specified values;
o Default values - size of the device’s screen.
• httpConnectTimeout() sets the maximum waiting time (in milliseconds) for establishing an HTTP connection;
o Default value - 5 seconds
• httpReadTimeout() sets the maximum time (in milliseconds) for loading an image from the Web;
o Default value - 30 seconds
• threadPoolSize() sets size of the thread pool. Each task on image loading and displaying is performed in a separate thread, and those threads, in which the image uploading from the Web occurs, get to the pool. Thus, the pool size determines the number of threads running simultaneously. Setting of a large pool size can significantly reduce the speed of the UI, for example, list scrolling could slow down.
o Default value - 5
• threadPriority() sets priority of all threads in the system (from 1 to 10), in which tasks are performed;
o Default value - 4
• calling denyCacheImageMultipleSizesInMemory() imposes a ban on storing different sizes of the same image in the memory. As full-size images are stored in the disk cache, and when loading into memory, they are reduced to the size of ImageView, in which they should be displayed, then there are cases when the same image has to be displayed first in a small view, and then in a big one. At the same time, two Bitmaps of different sizes representing the same image will be stored in the memory. This is the default behavior.
The denyCacheImageMultipleSizesInMemory() instruction ensures deletion of the previous size of the loaded image from cache in the memory.
• Using memoryCache(), you can specify the implementation of cache in the memory. You can use ready-made solutions (they all are realizations of limited size-cache; where by exceeding cache size, an object is removed from it by a certain algorithm):
o FIFOLimitedCache (the object is removed on the basis of First-In-First-Out)
o LargestLimitedCache (the largest-sized object is removed)
o UsingAgeLimitedCache (the object with the oldest date of access is removed)
o UsingFreqLimitedCache (the most rarely used object is removed)
Alternatively, you can implement your own version of the cache by implementing the interface MemoryCacheAware<String, Bitmap>;
o Default value - UsingFreqLimitedCache with memory limit to 2 MB
memoryCacheSize() sets the maximum cache size in the memory. In this case, the default cache is used - UsingFreqLimitedCache.
o Default value - 2 MB
• Using discCache(), you can define cash implementation in the file system. You can use ready-made solutions (where the files matching certain URLs are named as hash codes of these URLs):
o UnlimitedDiscCache (usual cache, no restrictions)
o FileCountLimitedDiscCache (cache with limited size)
o TotalSizeLimitedDiscCache (cache with limited files number)
Alternatively, you can define your own cache implementation by DiscCacheAware interface.
o Default value - UnlimitedDiscCache
• discCacheSize(int) specifies the maximum cache size in the file system. In this case, the TotalSizeLimitedDiscCache is used.
• discCacheFileCount(int) specifies the maximum number of files in the disk cache. In this case, the FileCountLimitedDiscCache is used.
• Using defaultDisplayImageOptions(), you can set image displaying options, which will be used for all calls of the displayimage(...) method, where custom options were not passed. I’ll discuss these options in details below.

We can construct a configuration object ourselves or trust a developer (i.e. me) and use the default configuration:

ImageLoaderConfiguration config =
ImageLoaderConfiguration.createDefault(context);

Thus, the configuration is created. Now, the ImageLoader can be initialized with it:

ImageLoader.getInstance().init(config);

That's all, the ImageLoader is ready to use. I'll tell you about this in the next article.

comments powered by Disqus