Load Image From Web In Android

Load Image to ImageView from Web Url 
 
In an Android application we need to set ImageView src as web url. The times we need to download the image using web request and then save the image in phone and set this to the particular ImageView, this will be the normal flow for setting an ImageView url from web server. If there are one or two images then it's okay but if there are a lot of images to load this will be a big problem and we need to handle all the requests and all the files. Here I am going to tell you how we can download images in the background and set to the corresponding ImageView as they are available.

In the task I have a ListView and its populated  at the runtime, that is, we need to download the data from web service to populate the ListView. This data contains a title and web url of the image to be shown in the ListView. After getting the data from web service we need to show the ListView with its title and a dummy image. On the time of getting each image from the internet we need to update the ImageView with the actual image. This is the task I am going to perform.
 
First we need to create the main layout file like the following it will contain only a listview.
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3. android:orientation="vertical" android:layout_width="match_parent"  
  4. android:layout_height="match_parent">  
  5.     <ListView  
  6. android:layout_width="match_parent"  
  7. android:layout_height="wrap_content"  
  8. android:id="@+id/listView"  
  9. android:layout_gravity="center_horizontal" />  
  10. </LinearLayout>  
In this listview we need to show the title and ImageView so create a custom layout for the list item and it should be like the following,
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3. android:orientation="horizontal" android:layout_width="match_parent"  
  4. android:layout_height="match_parent">  
  5.     <ImageView  
  6. android:layout_width="0dp"  
  7. android:layout_margin="10dp"  
  8. android:layout_weight=".25"  
  9. android:id="@+id/imageItem"  
  10. android:layout_height="match_parent" />  
  11.     <TextView  
  12. android:layout_width="0dp"  
  13. android:id="@+id/text"  
  14. android:layout_weight=".75"  
  15. android:layout_height="wrap_content" />  
  16. </LinearLayout>  
Now we need to call the initial JSON image that contains title and image url. For that we need to create an http communication class as Async task and here is the code below that will get the JSON data from webservice and will show it in the listview,
  1. @Override  
  2. protected Output doInBackground(Void...voids)  
  3. {  
  4.     BufferedReader in = null;  
  5.     String data = null;  
  6.     InputStream inputStream = null;  
  7.     String result = "";  
  8.     try  
  9.     {  
  10.         // create HttpClient  
  11.         HttpClient httpclient = new DefaultHttpClient();  
  12.         // make GET request to the given URL  
  13.         HttpResponse httpResponse = httpclient.execute(new HttpGet("https://randomapi.com/api/?key=LMW0-SW97-ISC4-FF25&id=t60ldyb&results=20"));  
  14.         // receive response as inputStream  
  15.         inputStream = httpResponse.getEntity().getContent();  
  16.         // convert inputstream to string  
  17.         if (inputStream != null)  
  18.             result = convertInputStreamToString(inputStream);  
  19.         else  
  20.             result = null;  
  21.     } catch (Exception e)  
  22.     {  
  23.         Log.d("InputStream", e.getLocalizedMessage());  
  24.         result = null;  
  25.     }  
  26.     Log.e("response----""" + result);  
  27.     if (result != null)  
  28.     {  
  29.         Output response = new Gson().fromJson(  
  30.             result, Output.class);  
  31.         return response;  
  32.     }  
  33.     return null;  
  34. }  
  35.   
  36. private static String convertInputStreamToString(InputStream inputStream) throws IOException   
  37. {  
  38.     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));  
  39.     String line = "";  
  40.     String result = "";  
  41.     while ((line = bufferedReader.readLine()) != null)  
  42.         result += line;  
  43.     inputStream.close();  
  44.     return result;  
  45. }  
Now we need to call the Asynctask to load this JSON from our mainActivity,
  1. HttpHelper httpHelper = new HttpHelper(this,getActivity());  
  2.  httpHelper.execute();  
Now we need to create an interface that will handle the downloaded image,
  1. public interface ImageCallback  
  2. {  
  3.     public void setImage(String tag, Bitmap bitmap);  
  4. }
Now we need to create a class for the Image Downloader this class will download the image and handle this image,
  1. class ImageDownloaderTask extends AsyncTask < String, Void, Bitmap >  
  2. {  
  3.     // private final WeakReference<ImageView> imageViewReference;  
  4.     String tag = null;  
  5.   
  6.     private ImageCallback imageCallback = null;  
  7.     public ImageDownloaderTask(ImageCallback imageCallback, String TAG)  
  8.     {  
  9.         //imageViewReference = new WeakReference<ImageView>(imageView);  
  10.         this.imageCallback = imageCallback;  
  11.         this.tag = TAG;  
  12.     }  
  13.     @Override  
  14.     protected Bitmap doInBackground(String...params)   
  15.     {  
  16.         HttpURLConnection urlConnection = null;  
  17.         try  
  18.         {  
  19.             URL uri = new URL(params[0]);  
  20.             urlConnection = (HttpURLConnection) uri.openConnection();  
  21.             int statusCode = urlConnection.getResponseCode();  
  22.             if (statusCode != HttpStatus.SC_OK)  
  23.             {  
  24.                 return null;  
  25.             }  
  26.             InputStream inputStream = urlConnection.getInputStream();  
  27.             if (inputStream != null)  
  28.             {  
  29.                 Bitmap bitmap = BitmapFactory.decodeStream(inputStream);  
  30.                 return bitmap;  
  31.             }  
  32.         } catch (Exception e)  
  33.         {  
  34.             urlConnection.disconnect();  
  35.             Log.w("ImageDownloader""Error downloading image from ");  
  36.         } finally {  
  37.             if (urlConnection != null)  
  38.             {  
  39.                 urlConnection.disconnect();  
  40.             }  
  41.         }  
  42.         return null;  
  43.     }  
  44.     @Override  
  45.     protected void onPostExecute(Bitmap bitmap)   
  46.     {  
  47.         if (isCancelled())  
  48.         {  
  49.             bitmap = null;  
  50.         }  
  51.   
  52.         imageCallback.setImage(tag, bitmap);  
  53.     }  
  54.   
  55. }  
Here comes the main part of the listview that is the Adapter for binding the items to listview,
  1. public class ListAdapter extends BaseAdapter  
  2. {  
  3.     private ArrayList < ResultData > result = null;  
  4.     private Context context = null;  
  5.     LayoutInflater inflater;  
  6.     private ImageCallback imageCallback = null;  
  7.     private HashMap < String, Bitmap > imageMap = new HashMap < String, Bitmap > ();  
  8.   
  9.     public void addItem(String key, Bitmap bitmap)  
  10.     {  
  11.         if (imageMap.get(key) == null)  
  12.             imageMap.put(key, bitmap);  
  13.     }  
  14.     public ListAdapter(Context context, ArrayList < ResultData > result, ImageCallback imageCallback)  
  15.     {  
  16.         this.result = result;  
  17.         this.context = context;  
  18.         inflater = LayoutInflater.from(context);  
  19.         this.imageCallback = imageCallback;  
  20.     }  
  21.     @Override  
  22.     public int getCount()  
  23.     {  
  24.         return result.size();  
  25.     }  
  26.     @Override  
  27.     public Entity getItem(int i)   
  28.     {  
  29.         return result.get(i).getEntity();  
  30.     }  
  31.     @Override  
  32.     public long getItemId(int i)   
  33.     {  
  34.         return 0;  
  35.     }  
  36.     @Override  
  37.     public View getView(int arg0, View convertView, ViewGroup arg2)  
  38.     {  
  39.         ViewHolder viewHolder = new ViewHolder();  
  40.         if (convertView == null)  
  41.         {  
  42.             convertView = inflater.inflate(R.layout.list_item, null);  
  43.             viewHolder.titleText = (TextView) convertView.findViewById(R.id.text);  
  44.             viewHolder.imageItem = (ImageView) convertView.findViewById(R.id.imageItem);  
  45.             convertView.setTag(viewHolder);  
  46.         } else  
  47.         {  
  48.             viewHolder = (ViewHolder) convertView.getTag();  
  49.         }  
  50.         viewHolder.titleText.setText(getItem(arg0).getDescritpion());  
  51.         if (viewHolder.imageItem != null)  
  52.         {  
  53.             viewHolder.imageItem.setTag(getItem(arg0).getThumbnail());  
  54.             Bitmap bitmap = null;  
  55.             bitmap = imageMap.get(getItem(arg0).getThumbnail());  
  56.             if (bitmap == null)  
  57.                 new ImageDownloaderTask(imageCallback, getItem(arg0).getThumbnail()).execute(getItem(arg0).getThumbnail());  
  58.             else  
  59.                 viewHolder.imageItem.setImageBitmap(bitmap);  
  60.         }  
  61.   
  62.         return convertView;  
  63.   
  64.     }  
  65.     class ViewHolder  
  66.     {  
  67.         private TextView titleText = null;  
  68.         private ImageView imageItem = null;  
  69.     }  
  70. }  
Here we created a HashMap<String,Bitmap> this will store the downloaded images in the hashmap. and will avoid loading the same image while scrolling the listview. In the getview() of adapter we will check whether the image is available in the hashmap or  if not available then we will get it from the server. Please find the screen shot also,

 

Read more articles on Android: