Mobile Zone is brought to you in partnership with:

http://www.technotalkative.com/about/ Paresh has posted 21 posts at DZone. You can read more from them at their website. View Full User Profile

Be a Lazy But Productive Android Developer, Part 5: Image Loading Library

04.11.2014
| 14735 views |
  • submit to reddit

Welcome to part 5 of “Be a lazy but a productive android developer” series. If you are a lazy Android developer and looking for image loading library, which could help you to load image(s) asynchronously without writing a logic for downloading and caching images then this article is for you.

This series so far:

  • Part 1: We looked at RoboGuice, a dependency injection library by which we can reduce the boiler plate code, save time and there by achieve productivity during Android app development.
  • Part 2: We saw and explored about Genymotion, which is a rocket speed emulator and super-fast emulator as compared to native emulator. And we can use Genymotion while developing apps and can quickly test apps and there by can achieve productivity.
  • Part 3: We understood and explored about JSON Parsing libraries (GSON and Jackson), using which we can increase app performance, we can decrease boilerplate code and there by can optimize productivity.
  • Part 4: We talked about Card UI and explored card library, also created a basic card and simple card list demo.

In this part

In this part, we are going to talk about some image libraries using which we can load image(s) asynchronously, can cache images and also can download images into the local storage.

Required features for loading images

Almost every android app has a need to load remote images. While loading remote images, we have to take care of below things:

  • Image loading process must be done in background (i.e. asynchronously) to avoid blocking UI main thread.
  • Image recycling image should be done.
  • Image should be displayed once its loaded successfully.
  • Images should be cached in local memory for the later use.
  • If remote image gets failed (due to network connection or bad url or any other reasons) to load then it should be managed perfectly for avoiding duplicate requests to load the same again, instead it should load if and only if net connection is available.
  • Memory management should be done efficiently.

In short, we have to write a code to manage each and every aspects of image loading but there are some awesome libraries available, using which we can load/download image asynchronously. We just have to call the load image method and success/failure callbacks.

Asynchronous image loading

Consider a case where we are having 50 images and 50 titles and we try to load all the images/text into the listview, it won’t display anything until all the images get downloaded.

Here Asynchronous image loading process comes in picture. Asynchronous image loading is nothing but a loading process which happens in background so that it doesn’t block main UI thread and let user to play with other loaded data on the screen. Images will be getting displayed as and when it gets downloaded from background threads.

Asynchronous image loading libraries

  1. Nostra’s Universal Image loader – https://github.com/nostra13/Android-Universal-Image-Loader
  2. Picasso – http://square.github.io/picasso/
  3. UrlImageViewHelper by Koush
  4. Volley - By Android team members @ Google
  5. Novoda’s Image loader – https://github.com/novoda/ImageLoader

Let’s have a look at examples using Picasso and Universal Image loader libraries.

Example 1: Nostra’s Universal Image loader

Image loading using UniversalImageLoader

Step 1: Initialize ImageLoader configuration

?
public class MyApplication extends Application{
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
// Create global configuration and initialize ImageLoader with this configuration
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).build();
ImageLoader.getInstance().init(config);
}
}

Step 2: Declare application class inside Application tag in AndroidManifest.xml file

?
<application android:name="MyApplication">

Step 3: Load image and display into ImageView

?
ImageLoader.getInstance().displayImage(objVideo.getThumb(), holder.imgVideo);

Now, Universal Image loader also provides a functionality to implement success/failure callback to check whether image loading is failed or successful.

?
ImageLoader.getInstance().displayImage(photoUrl, imgView,
new ImageLoadingListener() {
@Override
public void onLoadingStarted(String arg0, View arg1) {
// TODO Auto-generated method stub
findViewById(R.id.EL3002).setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(String arg0, View arg1,
FailReason arg2) {
// TODO Auto-generated method stub
findViewById(R.id.EL3002).setVisibility(View.GONE);
}
@Override
public void onLoadingComplete(String arg0, View arg1,
Bitmap arg2) {
// TODO Auto-generated method stub
findViewById(R.id.EL3002).setVisibility(View.GONE);
}
@Override
public void onLoadingCancelled(String arg0, View arg1) {
// TODO Auto-generated method stub
findViewById(R.id.EL3002).setVisibility(View.GONE);
}
});

Example 2: Picasso

Image loading straight way:

?
Picasso.with(context).load("http://postimg.org/image/wjidfl5pd/").into(imageView);

Image re-sizing:

?
Picasso.with(context)
.load(imageUrl)
.resize(100, 100)
.centerCrop()
.into(imageView)

Example 3: UrlImageViewHelper library

UrlImageViewHelper by Koush

It’s an android library that sets an ImageView’s contents from a url, manages image downloading, caching, and makes your coffee too.

UrlImageViewHelper will automatically download and manage all the web images and ImageViews. Duplicate urls will not be loaded into memory twice. Bitmap memory is managed by using a weak reference hash table, so as soon as the image is no longer used by you, it will be garbage collected automatically.

Image loading straight way:

?
UrlImageViewHelper.setUrlDrawable(imgView, "http://yourwebsite.com/image.png");

Placeholder image when image is being downloaded:

?
UrlImageViewHelper.setUrlDrawable(imgView, "http://yourwebsite.com/image.png", R.drawable.loadingPlaceHolder);

Cache images for a minute only:

?
UrlImageViewHelper.setUrlDrawable(imgView, "http://yourwebsite.com/image.png", null, 60000);

Example 4: Volley library

Yes Volley is a library developed and being managed by some android team members at Google, it was announced by Ficus Kirkpatrick during the last I/O. I wrote an article about Volley library 10 months back :) , read it and give it a try if you haven’t used it yet.

Let’s look at an example of image loading using Volley.

Step 1: Take a NetworkImageView inside your xml layout.

?
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/imgDemo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"/>

Step 2: Define a ImageCache class

Yes you are reading title perfectly, we have to define an ImageCache class for initializing ImageLoader object.

?
public class BitmapLruCache
extends LruCache<String, Bitmap>
implements ImageLoader.ImageCache {
public BitmapLruCache() {
this(getDefaultLruCacheSize());
}
public BitmapLruCache(int sizeInKiloBytes) {
super(sizeInKiloBytes);
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
@Override
public Bitmap getBitmap(String url) {
return get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
public static int getDefaultLruCacheSize() {
final int maxMemory =
(int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
return cacheSize;
}
}

Step 3: Create an ImageLoader object and load image
Create an ImageLoader object and initialize it with ImageCache object and RequestQueue object.

?
ImageLoader.ImageCache imageCache = new BitmapLruCache();
ImageLoader imageLoader = new ImageLoader(Volley.newRequestQueue(context), imageCache);

Step 4: Load an image into ImageView

?
NetworkImageView imgAvatar = (NetworkImageView) findViewById(R.id.imgDemo);
imageView.setImageUrl(url, imageLoader);

Which library to use?

Can you decide which library you would use? Let us know which and what are the reasons? :)

Selection of the library is always depends on the requirement. Let’s look at the few fact points about each library so that you would able to compare exactly and can take decision.

Picasso:

  • It’s just a one liner code to load image using Picasso.
  • No need to initialize ImageLoader and to prepare a singleton instance of image loader.
  • Picasso allows you to specify exact target image size. It’s useful when you have memory pressure or performance issues, you can trade off some image quality for speed.
  • Picasso doesn’t provide a way to prepare and store thumbnails of local images.
  • Sometimes you need to check image loading process is in which state, loading, finished execution, failed or cancelled image loading. Surprisingly It doesn’t provide a callback functionality to check any state. “fetch()” dose not pass back anything. “get()” is for synchronously read, and “load()” is for asynchronously draw a view.

Universal Image loader (UIL):

  • It’s the most popular image loading library out there. Actually, it’s based on the Fedor Vlasov’s project
  • which was again probably a very first complete solution and also a most voted answer (for the image loading solution) on Stackoverflow.

  • UIL library is better in documentation and even there’s a demo example which highlights almost all the features.
  • UIL provides an easy way to download image.
  • UIL uses builders for customization. Almost everything can be configured.
  • UIL doesn’t not provide a way to specify image size directly you want to load into a view. It uses some rules based on the size of the view. Indirectly you can do it by mentioning ImageSize argument in the source code and bypass the view size checking. It’s not as flexible as Picasso.

Volley:

  • It’s officially by Android dev team, Google but still it’s not documented.
  • It’s just not an image loading library only but an asynchronous networking library
  • Developer has to define ImageCache class their self and has to initialize ImageLoader object with RequestQueue and ImageCache objects.

So now I am sure now you can be able to compare libraries. Choosing library is a bit difficult talk because it always depends on the requirement and type of projects. If the project is large then you should go for Picasso or Universal Image loader. If the project is small then you can consider to use Volley librar, because Volley isn’t an image loading library only but it tries to solve a more generic solution.).

I suggest you to start with Picasso. If you want more control and customization, go for UIL.

Read more:

  1. http://blog.bignerdranch.com/3177-solving-the-android-image-loading-problem-volley-vs-picasso/
  2. http://stackoverflow.com/questions/19995007/local-image-caching-solution-for-android-square-picasso-vs-universal-image-load
  3. https://plus.google.com/103583939320326217147/posts/bfAFC5YZ3mq

Hope you liked this part of “Lazy android developer: Be productive” series. Till the next part, keep exploring image loading libraries mentioned above and enjoy!

Published at DZone with permission of its author, Paresh Mayani. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)