Mark Molina
Mark Molina

Reputation: 5077

Multiple downloads async

In java I want to download multiple images for my imageview at once. I found this code which does exact that but its only downloading the first image. I think it has something to do with the first line in the doInBackground. How can I tweak this code so it loops imageViews and downloads every image for imageViews.

package com.denederlandsewateren.daos;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;

public class DownloadImageTaskDAO extends AsyncTask<ImageView, Void, Bitmap> {

    ImageView imageView = null;

    @Override
    protected Bitmap doInBackground(ImageView... imageViews) {
        this.imageView = imageViews[0];
        return download_Image((String)imageView.getTag());
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        imageView.setImageBitmap(result);
    }

    private Bitmap download_Image(String url) {
        //---------------------------------------------------
        Bitmap bm = null;
        try {
            URL aURL = new URL(url);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            bm = BitmapFactory.decodeStream(bis);
            bis.close();
            is.close();
        } catch (IOException e) {
            Log.e("Hub","Error getting the image from server : " + e.getMessage().toString());
        } 
        return bm;
        //---------------------------------------------------
    }

}

called from here:

public void setImages(String url1, String url2) {
        image1.setTag(url1);
        image2.setTag(url2);
        DownloadImageTaskDAO imageDAO = new DownloadImageTaskDAO();
        imageDAO.execute(image1, image2);
    }

Upvotes: 2

Views: 1558

Answers (3)

Flynn81
Flynn81

Reputation: 4178

Do not use an AsyncTask, instead consider using a IntentService with a ResultReceiver passed as an extra to the service. IntentService's perform better under load (like downloading multiple images) because they use HandlerThread's as opposed to AsyncTasks which use ThreadPoolExecutor.

IntentService

ResultReceiver

Upvotes: 1

Niklas Ekman
Niklas Ekman

Reputation: 960

@Override
protected Bitmap doInBackground(ImageView... imageViews) {
    this.imageView = imageViews[0];
    return download_Image((String)imageView.getTag());
}

You are processing only the first argument sent to the AsyncTask. With the parameter ImageView... you can send one, two, N elements or arrays. Loop through the arguments and process each one.

You can use the return from doInBackground, in onPostExecute and personally I try to utilize that as much as I can for the sake of encapsulation.

Overall I suggest you read the AsyncTask reference on Android Developers to get a better understanding of AsyncTasks.

I did rewrite your code and below should theoretically work (it's not tested).

public class DownloadImageTaskDAO extends AsyncTask<ImageView, Void, ArrayList<DownloadImageTaskDAO.Container>> {

    @Override
    protected ArrayList<Container> doInBackground(ImageView... imageViews) {
         ArrayList<Container> results = new ArrayList<Container>(imageViews.length);

         for (ImageView imageView : imageViews) {
             Container tmp = new Container();
             tmp.holder = imageView;
             tmp.image = download_Image(imageView.getTag().toString());
             results.add(tmp);
         }

         return results;
    }

    @Override
    protected void onPostExecute(ArrayList<Container> result) {
        for (Container container : result) {
            container.holder.setImageBitmap(container.image);
        }
    }

    private Bitmap download_Image(String url) {
        ....
    }

    class Container {
        ImageView holder;
        Bitmap image;
    }
}

Upvotes: 4

Dixit Patel
Dixit Patel

Reputation: 3192

i suggest this way to implement your code

Hope it will helpfull to you download Multiple images with single AsyncTask call.

Asynctask Call Method

public void setImages(String[] urls)
{
   DownloadImageTaskDAO imageDAO = new DownloadImageTaskDAO();

   if(int i= 0; i< urls.lenght();i++)
   {
        image.setTag(urls[i]);
        imageDAO.execute(image).get();
    }
}

DownloadImageTaskDAO Class :

public class DownloadImageTaskDAO extends AsyncTask<ImageView, Void, Bitmap> {

    ImageView imageView = null;

    @Override
    protected Bitmap doInBackground(ImageView imageView) {
        this.imageView = imageView;
        return download_Image((String)imageView.getTag());
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        imageView.setImageBitmap(result);
    }

    private Bitmap download_Image(String url) {
        //---------------------------------------------------
        Bitmap bm = null;
        try {
            URL aURL = new URL(url);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            bm = BitmapFactory.decodeStream(bis);
            bis.close();
            is.close();
        } catch (IOException e) {
            Log.e("Hub","Error getting the image from server : " + e.getMessage().toString());
        } 
        return bm;
        //---------------------------------------------------
    }

}

Upvotes: 0

Related Questions