Android Load Image from URL using Universal Image Loader (UIL) and FunDapter - Part 1

How to Lazy Load Images from the Web, Cache the Images, Scroll Down But No Images Disappeared, and Place It in a Nice Custom ListView...

Image Android Lazy Image Loading by kosalgeek.com

How to Lazy Load Images from the Web, Cache the Images, Scroll Down But No Images Disappeared, and Place It in a Nice Custom ListView?

Written by Oum Saokosal, Author of KosalGeek.

INTRODUCTION

On a browser, you can easily see a Web page full of texts, images, and interactivity. It is fairly easy to achieve that by simply opening a text editor, putting up some HTML, saving it as .html, and then you already see a Web page. If you want to place an image, add
<img src="http://site.com/image.png" /> somewhere in the body tag, that's it.

For mobile such as Android to load image from URL, the world has changed. There are two ways to get an image displayed on your smart device, first by using a WebView widget and another way by using a simple ImageView widget. The WebView will take up your whole screen and become another slaggy browser. The latter lets you mix it with other widgets, e.g. TextView, Button, etc.

Here in this article, we are going to talk about the ImageView. How to load an image, cache it, specifically how to lazy-load an image from the Web? Surprisingly there is no a default API for that. However, there are a bunch of good unofficial libraries out there, for example, Glide, Picasso, Universal Image Loader (UIL) etc. I tested all of this API, but personally I found UIL worked best for me. It is allowed to make any configuration you wish, including image size and cache. Some people prefer Picasso but I stopped testing it since I rotated the image and it crashed. There must be a solution for that but it didn't convince me well. For now, I use UIL for this post.

In this sample, I want to make a custom ListView with an image filled up a phone screen width and keep the ratio for the height. And above the image, I put two TextViews. Just for the image credit, I put another TextView below the image to display its URL. About the custom Adapter for the custom ListView, I use FunDapter library from Ami Goldenberg. I also wrote an article on how to use FunDapter for a custom ListView. The FunDapter library will help you to skip the custom adapter part. For now, no worry about that yet; I will go through each points of those. So below is my final intention of the look:

Image Android Lazy Image Loading from Web by kosalgeek.com

BASIC IMAGE LOADING

First, let's recall the basic of image loading.

Set Image From Drawable

Assume you have an ImageView imageView in your layout. And you have an image sunset.jpg in your drawable folder. Then you can set your image by the TextView's setImageResource method. Please note that the image in Drawable folder cannot contain any space or any special character at all. It allows a to z, A to Z, 0 to 9 and _ (underscores).
ImageView imageView;
imageView = (ImageView)findViewById(R.id.imageView);
String imageName = "sunset";
int imageResource = getResources().
              getIdentifier(imageName, "drawable", getPackageName());
imageView.setImageResource(imageResource);

However, it is better to create a method for later uses.
private int getImageFromDrawable(String imageName){
    int imageResource = getResources().getIdentifier(
                       imageName, "drawable", getPackageName());
    return imageResource;
}

imageView.setImageResource(getImageFromDrawable("sunset"));

Set Image from Assets

Assets is s special folder in Android that allows you to store any kind of files including text, JSON, XML, audio, video and picture files. A big difference between an image in Drawable and Assets is in the Assets, the image file name can contain spaces, special characters, and an extension. But the Assets folder does not come as a default, you need to create one. For Android Studio, you should go to Project perspective > Under your project name, e.g. TestImage, unfold app > src > main. In the main folder, right click to open a context menu and choose Create New Folder > Enter Assets > OK. You can copy images from somewhere else and paste them in there. Below is a screenshot.
Image Create Assets in Android Studio by KosalGeek.com

Here is a sample code to load an image from Assets:
private Bitmap getBitmapFromAssets(String fileName) throws IOException {
    AssetManager assetManager = getAssets();

    InputStream istr = assetManager.open(fileName);
    Bitmap bitmap = BitmapFactory.decodeStream(istr);

    return bitmap;
}

ImageView imageView2;
imageView2 = (ImageView)findViewById(R.id.imageView2);
try {
    imageView2.setImageBitmap(getBitmapFromAssets("cub cake.jpg"));
} catch (IOException e) {
    Toast.makeText(this, "Error Image Path", Toast.LENGTH_SHORT).show();
    //Handle your exception when image path not found.
}
To load an image from Assets, there are different ways to do that but I prefer this way because you have a nice try-catch block to catch an exception when the image is not found.

Set Image from the Web

Since Android 3.0 API 11 (Honeycombs), you are no longer allowed to use the main UI thread to connect to a URL. Android introduced AsyncTask class to work as a background thread to connect to the Web. You can write your own library by extending AsyncTask class and using Java's InputStream to read the data from a given URL. But we are not gonna do that. We are going to use a well-maintained, popular library Universal Image Loader (UIL) created by Sergey Tarasevich, where you can download it from his GitHub repo.

Actually, the library does all the image stuff, loading images from Drawable, Assets, Content, File, and Web URL that I mentioned above.

Use UIL to Load Image from the Web

In the Sergey's Universal Image Loader (UIL) repo, he already created a good documentation from How to Setup to Configuration to Display Options. But here I want to bring out some important points.

Setup

1. Download JAR

You can manually download the JAR file from his GitHub. It might be a good idea for people who are living in a place where the Internet is not stable and want to share it to their colleagues. However, you might lose the benefit of a new update because the library is not perfect yet, no one is perfect, and still maintained and it releases a new version every now and then. If you decided to use this Jar, make sure you add it as a library by copying the Jar file into libs folder. Check this link to see how to do that.

2. Gradle Dependency

It is the easiest way. What you have to do is to add the bellowed code to your project dependencies:
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.4'
Just in case, I made a snapshot of that.
Image Add Grade in Android Studio by kosalgeek

Configuration

The configuration varies from one to another since the library gives all the freedom to users. In this particular article, however, I am going to configure it in order to response to my question "How to Lazy Load Images from the Web, Cache Images, Scroll Down But No Images Disappeared, and Place It in a Nice Custom ListView?" But for an answer to the Customer ListView, we will work on it later on, in the FunDapter section. So below is a configuration you should do:

Step 1 - Permissions

Since you connect to the Web, you must add the Internet permission. And the UIL needs to cache, so you need to add another permission Write_External_Storage. Place these two permissions in AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Step 2 - Image Options and Caching

Place this configuration code just below super.setContentView(R.layout.activity_main) in the onCreate method of your project because it needs to initiate the configuration before you display an image.
final DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
            .cacheInMemory(true)
            .cacheOnDisk(true)
            .showImageOnLoading(android.R.drawable.stat_sys_download)
            .showImageForEmptyUri(android.R.drawable.ic_dialog_alert)
            .showImageOnFail(android.R.drawable.stat_notify_error)
            .considerExifParams(true)
            .bitmapConfig(Bitmap.Config.RGB_565)
            .imageScaleType(ImageScaleType.EXACTLY_STRETCHED) //filled width
            .build();
                
final ImageLoaderConfiguration config = new ImageLoaderConfiguration
            .Builder(getApplicationContext())
            .threadPriority(Thread.NORM_PRIORITY - 2)
            .denyCacheImageMultipleSizesInMemory()
            .diskCacheFileNameGenerator(new Md5FileNameGenerator())
            .tasksProcessingOrder(QueueProcessingType.LIFO)
            .defaultDisplayImageOptions(defaultOptions)
            .build();
ImageLoader.getInstance().init(config);
I set up all the necessary options such as image cache, image error loading, image scale, thread etc. You can read this article about each options.

Please note that the option .imageScaleType(ImageScaleType.EXACTLY_STRETCHED) is the most important one to make an image filled up the screen width. You might think the image scale type EXACTLY_STRETCHED will make your image stretched but it is not. It is because I set the image layout_height as wrap_content. This is the setting of the ImageView:
<ImageView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/imageView3" />
So these two options EXACTLY_STRETCHED and layout_width="fill_parent" can make your image fill up the whole screen width regardless of your screen resolution. And layout_height="wrap_content" will keep the ratio of your image height.

Step Final - Setting Image From Web URL

Assume you have an ImageView imageView3 in your layout as shown above. The the code for displaying image from the Web URL in your java file should be:
ImageView imageView3 = (ImageView)findViewById(R.id.imageView3);
String url = "http://img06.deviantart.net/3659/i/2004/05/2/e/pink_flower.jpg";
ImageLoader.getInstance().displayImage(url, imageView3);
After you run it, you should see this:
IMAGE UIL image loading - kosalgeek.com
Note that, if you have already made your Android load image from URL once, and you unplug it, you still see the image because of the image caching. Isn't it awesome?

Just in case you want to test this part of the sample, I uploaded this sample code to my GitHub at https://github.com/kosalgeek/TestImage

Go to Part 2 - How to Set Images to a Custom ListView?

COMMENTS

Name

Android Java for Android
false
ltr
item
Android Programming Language Step by Step | KosalGeek: Android Load Image from URL using Universal Image Loader (UIL) and FunDapter - Part 1
Android Load Image from URL using Universal Image Loader (UIL) and FunDapter - Part 1
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHaKk7V1C1GOovqFGVgI8lY9IIADqqM9_DxAdN_sWvs_uOJ9QevIz0oQO7lnWVAQy65ETzKGPQCCi6JUC6BN1tUSM2nddWrjjxymbwMfAgWTIRfBOmZq9kY6o4_2tpM5f5kdWHjPGVTno/s320/Screen+Shot+2015-09-17+at+10.28.37+AM.png
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHaKk7V1C1GOovqFGVgI8lY9IIADqqM9_DxAdN_sWvs_uOJ9QevIz0oQO7lnWVAQy65ETzKGPQCCi6JUC6BN1tUSM2nddWrjjxymbwMfAgWTIRfBOmZq9kY6o4_2tpM5f5kdWHjPGVTno/s72-c/Screen+Shot+2015-09-17+at+10.28.37+AM.png
Android Programming Language Step by Step | KosalGeek
https://kosalgeek.blogspot.com/2015/09/android-load-image-from-url.html
https://kosalgeek.blogspot.com/
http://kosalgeek.blogspot.com/
http://kosalgeek.blogspot.com/2015/09/android-load-image-from-url.html
true
1541123312426289231
UTF-8
Not found any posts VIEW ALL Readmore Reply Cancel reply Delete By Home PAGES POSTS View All RECOMMENDED FOR YOU LABEL ARCHIVE SEARCH ALL POSTS Not found any post match with your request Back Home Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sun Mon Tue Wed Thu Fri Sat January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec just now 1 minute ago $$1$$ minutes ago 1 hour ago $$1$$ hours ago Yesterday $$1$$ days ago $$1$$ weeks ago more than 5 weeks ago Followers Follow THIS CONTENT IS PREMIUM Please share to unlock Copy All Code Select All Code All codes were copied to your clipboard Can not copy the codes / texts, please press [CTRL]+[C] (or CMD+C with Mac) to copy