How to implement uploading images to a list in a separate thread on Android

At the request of workers, an article on the method of downloading images to a list in a separate thread on Android.
Task:
Implement a mechanism for downloading images from the Internet and displaying them in a list. At the same time, the loading of images should be implemented in a separate stream, in order to avoid "freezing" of the application UI.
Implementation:
To accomplish this task, a standard ListView widget and an adapter, ArrayAdapter, were used. To work with images, the ImageManager helper class was created, which has two methods, downloadImage () and fetchImage (). The first downloads images from the Internet. The second - causes the images to be loaded in a separate stream and sets the result in ImageView.
Usage example:
We will consider the implementation of the task on the example of my project. And I will refer to his code in the article.
Sources: fileshare.in.ua/3053597
APK: fileshare.in.ua/3053596
Description of implementation:
Let's take a closer look at each of ImageManager's methods:
- package com.rudenko.android.ListIconFetching;
-
- import java.io.BufferedInputStream;
- import java.io.IOException;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
-
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.widget.ImageView;
-
- public class ImageManager {
- private final static String TAG = "ImageManager";
-
- /** Private constructor prevents instantiation from other classes */
- private ImageManager () {}
-
- public static void fetchImage(final String iUrl, final ImageView iView) {
- if ( iUrl == null || iView == null )
- return;
-
- final Handler handler = new Handler() {
- @Override
- public void handleMessage(Message message) {
- final Bitmap image = (Bitmap) message.obj;
- iView.setImageBitmap(image);
- }
- };
-
- final Thread thread = new Thread() {
- @Override
- public void run() {
- final Bitmap image = downloadImage(iUrl);
- if ( image != null ) {
- Log.v(TAG, "Got image by URL: " + iUrl);
- final Message message = handler.obtainMessage(1, image);
- handler.sendMessage(message);
- }
- }
- };
- iView.setImageResource(R.drawable.icon);
- thread.setPriority(3);
- thread.start();
- }
-
- public static Bitmap downloadImage(String iUrl) {
- Bitmap bitmap = null;
- HttpURLConnection conn = null;
- BufferedInputStream buf_stream = null;
- try {
- Log.v(TAG, "Starting loading image by URL: " + iUrl);
- conn = (HttpURLConnection) new URL(iUrl).openConnection();
- conn.setDoInput(true);
- conn.setRequestProperty("Connection", "Keep-Alive");
- conn.connect();
- buf_stream = new BufferedInputStream(conn.getInputStream(), 8192);
- bitmap = BitmapFactory.decodeStream(buf_stream);
- buf_stream.close();
- conn.disconnect();
- buf_stream = null;
- conn = null;
- } catch (MalformedURLException ex) {
- Log.e(TAG, "Url parsing was failed: " + iUrl);
- } catch (IOException ex) {
- Log.d(TAG, iUrl + " does not exists");
- } catch (OutOfMemoryError e) {
- Log.w(TAG, "Out of memory!!!");
- return null;
- } finally {
- if ( buf_stream != null )
- try { buf_stream.close(); } catch (IOException ex) {}
- if ( conn != null )
- conn.disconnect();
- }
- return bitmap;
- }
- }
* This source code was highlighted with Source Code Highlighter.FetchImage () method:
public static void fetchImage(final String iUrl, final ImageView iView);Input parameters:
iUrl - URL to the image to download;
iView - link to the ImageView widget to which the image will be assigned after loading.
Both parameters are required.
Result:
The function does not return anything.
Short description:
The function creates a stream for loading the image. At boot time, a standard image is set in the input ImageView. After the download is complete, the image input ImageView is updated loaded.
A few words about the stream: on line 46, the priority of the stream is lowered. This is done so that this thread does not take the resources necessary for the correct operation of the application.
DownloadImage () method:
public static Bitmap downloadImage(String iUrl);Input parameters:
iUrl - URL to the image to download
Result:
Image downloaded from the Internet, or Null - if the operation was not successful.
Short description:
The function creates a connection to the server where the image is located. An input stream is received, which is then passed to BitmapFactory to create the image.
How to use ImageManager:
Consider the example to the article. The FetchImageAdapter.getView () method uses the following line to load images in the ImageView of the list row:
ImageManager.fetchImage(android.image, holder.ib_logo);where android.image is the URL to the image and holder.ib_logo is the ImageView of the list row.
Conclusion:
This mechanism is suitable for downloading images from the Internet in a parallel stream, for any ImageView Android widget. That is, this mechanism can be used not only for a specific task.
PS use on health.