Recently, we have presented you Glide, a great library recommended by Google to load easily images on Android. It offers you some interesting features out of the box like disk and memory caching for example. Today, we’re going to present you a direct concurrent of Glide : Universal Image Loader.

ic_launcher_uil

Universal Image Loader has been created to provide a powerful, flexible and highly customizable solution to load images easily on Android offering also features to cache and display images. It offers to developers a lot of options to customize the way the library load and cache images. Library has been created by an indie developer and is a top project on GitHub : https://github.com/nostra13/Android-Universal-Image-Loader . Solution is great but presents a major disadvantage comparing to Glide, development has been stopped since the end of 2015 due to lack of time. But, like the project is open source, you are free to use it and to fork if you want.

Like announced on the GitHub page of Universal Image Loader, the library offers the following features :

  • Multithread image loading (asynchronous or synchronous)
  • Large choice of customization for the ImageLoader (thread executors, downloader, decoder, memory and disk cache, display image options, …)
  • Large choice of customization for the display of images with possibility to define decoding options, bitmap processing and displaying, …
  • Disk and / or memory caching out of the box
  • Listener for the loading process with possibility to get data about downloading progress

With all these features, Universal Image Loader is compatible from Android 2.0 until Android 6.0 Marshmallow.

Installation

Like always, first step is to install the library in your project. You can choose to use Universal Image Loader at the JAR format if you still use Eclipse ADT but in that tutorial, we’re going to use Android Studio, the official Android IDE. So, we add the following Gradle dependency in the build.gradle file :


compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'

 

Android Manifest configuration

Since Universal Image Loader will be used to download images from internet, you need to add the android.permission.INTERNET in your Android Manifest. Furthermore, you could have to add the android.permission.WRITE_EXTERNAL_STORAGE permission if you wish to use the caching images on SD Card feature. So, the following permissions should be in your Android Manifest :


<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 

Load your first image

Now, you are ready to load you first image in Android application with Universal Image Loader. The first image will be the SSaurel’s logo that is here : http://www.ssaurel.com/tmp/logo_ssaurel.png . Code should be like that :


ImageLoader imageLoader = ImageLoader.getInstance();
String imageUri = "http://www.ssaurel.com/tmp/logo_ssaurel.png";

imageLoader.loadImage(imageUri, new SimpleImageLoadingListener() {
  @Override
  public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
    // use the loaded image …
  }
});

 

Configure Universal Image Loader

Like said previously, Universal Image Loader has a large choice of configuration options for the loading process. Configurations must be applied on the ImageLoader singleton instance directly before the call to load images. The configuration applied is global to the application. The following example, coming from the official documentation, shows all the options you can use to configure your ImageLoader instance :


ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
  .memoryCacheExtraOptions(480, 800) // default = device screen dimensions
  .diskCacheExtraOptions(480, 800, null)
  .taskExecutor(...)
  .taskExecutorForCachedImages(...)
  .threadPoolSize(3) // default
  .threadPriority(Thread.NORM_PRIORITY - 2) // default
  .tasksProcessingOrder(QueueProcessingType.FIFO) // default
  .denyCacheImageMultipleSizesInMemory()
  .memoryCache(new LruMemoryCache(2 * 1024 * 1024))
  .memoryCacheSize(2 * 1024 * 1024)
  .memoryCacheSizePercentage(13) // default
  .diskCache(new UnlimitedDiskCache(cacheDir)) // default
  .diskCacheSize(50 * 1024 * 1024)
  .diskCacheFileCount(100)
  .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
  .imageDownloader(new BaseImageDownloader(context)) // default
  .imageDecoder(new BaseImageDecoder()) // default
  .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
  .writeDebugLogs()
  .build();

// Apply configuration
ImageLoader.getInstance().init(config);

 

Display an image

Universal Image Loader lets you to display directly an image to download in a View. At this effect, the displayImage() method is provided. Considering you have an ImageView named imageView, you can download the SSaurel’s logo in that image like that :


String imageUri = "http://www.ssaurel.com/tmp/logo_ssaurel.png";
imageLoader.displayImage(imageUri, imageView);

 

Configuration display process

You have also a large choice of options to configure the display process. Display options are defined via DisplayImageOptions class. These options are local for every display task and can be applied via options parameter on the displayImage() method. Coming from the official documentation, you can find here an example of all display options available :


DisplayImageOptions options = new DisplayImageOptions.Builder()
  .showImageOnLoading(R.drawable.ic_stub) // resource or drawable
  .showImageForEmptyUri(R.drawable.ic_empty) // resource or drawable
  .showImageOnFail(R.drawable.ic_error) // resource or drawable
  .resetViewBeforeLoading(false) // default
  .delayBeforeLoading(1000)
  .cacheInMemory(false) // default
  .cacheOnDisk(false) // default
  .preProcessor(...)
  .postProcessor(...)
  .extraForDownloader(...)
  .considerExifParams(false) // default
  .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default
  .bitmapConfig(Bitmap.Config.ARGB_8888) // default
  .decodingOptions(...)
  .displayer(new SimpleBitmapDisplayer()) // default
  .handler(new Handler()) // default
  .build();

Note that by default, Universal Image Loader is going to use configuration returned by ImageLoaderConfiguration.defaultDisplayImageOptions() method.

 

Listening loading process

Universal Image Loader has also all the features available to listen loading process. To achieve that and make a complete listening of the process, you must create an instance of ImageLoadingListener and you can use it like that with the displayImage() method :


imageLoader.displayImage(imageUri, imageView, options, new ImageLoadingListener() {
  @Override
  public void onLoadingStarted(String imageUri, View view) {
    ...
  }

  @Override
  public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
    ...
  }

  @Override
  public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
    ...
  }

  @Override
  public void onLoadingCancelled(String imageUri, View view) {
    ...
  }
 }, new ImageLoadingProgressListener() {
      @Override
      public void onProgressUpdate(String imageUri, View view, int current, int total) {
        ...
      }
 });

 

Miscellaneous

Obviously, Universal Image Loader can be more things that you can discover by your own by reading the official documentation. For example, you can also choose to define a specific size via the ImageSize class and define you want to download an image and result bitmap be fit to that specific size :


ImageSize targetSize = new ImageSize(80, 50); // specific size to fit result bitmap
imageLoader.loadImage(imageUri, targetSize, options, new SimpleImageLoadingListener() {
  @Override
  public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
    // use your bitmap …
  }
});

Finally, just a word on the URIs accepted by Universal Image Loader to load images. In addition to HTTP protocol, it supports file://, content://, assets:// and even drawable:// . Below, you will find a list of acceptable URIs examples :

  • “http://www.ssaurel.com/tmp/logo_ssaurel.png” // from Web
  • “file:///mnt/sdcard/logo_ssaurel.png” // from SD card
  • “file:///mnt/sdcard/hearing_test.mp4” // from SD card (video thumbnail)
  • “content://media/external/images/media/13” // from content provider
  • “content://media/external/video/media/13” // from content provider (video thumbnail)
  • “assets://logo_ssaurel.png” // from assets
  • “drawable://” + R.drawable.logo_ssaurel // from drawables (non-9patch images)

 

Conclusion

Offering a lot of configuration options, Universal Image Loader is a powerful and easy to use library to load images on Android. Besides, it has low memory consumption, no memory leaks and good balance between methods and size. It’s an ideal library for existing projects. However, the fact that the creator of the library stopped the development since the end of 2015 is a major concern to keep in mind when you will choose your library to load images on Android.