【问题标题】:Multiple downloads async多个下载异步
【发布时间】:2012-12-31 00:59:25
【问题描述】:

在 java 中,我想一次为我的 imageview 下载多个图像。我发现这段代码确实如此,但它只下载第一个图像。我认为这与 doInBackground 中的第一行有关。如何调整此代码,使其循环 imageViews 并下载 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;
        //---------------------------------------------------
    }

}

从这里调用:

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

【问题讨论】:

  • 如果你有兴趣,还有一个图书馆可以为你做这种事情。 github.com/koush/UrlImageViewHelper
  • 更改您的 AsyncTask 以在您的 doInBackground 中执行所有操作,不要让您的 AsyncTask 返回 ImageView 等。然后您可以通过 Array 设置图像,或将数组中的位置传递给 AsyncTask你想加载,然后在调用 asynctask 之前执行循环,我认为第二种意见更好,因为你将有多个异步任务同时获取图像。
  • github 库为我工作。快速简便的实施。将其发布为答案,以便我接受它作为答案。

标签: java android multithreading android-asynctask


【解决方案1】:

不要使用 AsyncTask,而是考虑使用带有 ResultReceiver 的 IntentService 作为额外的服务传递。 IntentService 在负载下表现更好(比如下载多个图像),因为它们使用 HandlerThread 而不是使用 ThreadPoolExecutor 的 AsyncTask。

IntentService

ResultReceiver

【讨论】:

    【解决方案2】:
    @Override
    protected Bitmap doInBackground(ImageView... imageViews) {
        this.imageView = imageViews[0];
        return download_Image((String)imageView.getTag());
    }
    

    您只处理发送到 AsyncTask 的第一个参数。使用参数ImageView...,您可以发送一个、两个、N 个元素或数组。循环遍历参数并处理每个参数。

    您可以在onPostExecute 中使用来自doInBackground 的返回值,并且我个人会尽可能多地利用它来为encapsulation 着想。

    总的来说,我建议您阅读 Android Developers 上的 AsyncTask 参考,以更好地了解 AsyncTasks。

    我确实重写了您的代码,下面理论上应该可以工作(未经测试)。

    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;
        }
    }
    

    【讨论】:

      【解决方案3】:

      我建议用这种方式来实现你的代码

      希望它对您下载Multiple images 与单个AsyncTask 呼叫有所帮助。

      异步任务调用方法

      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();
          }
      }
      

      下载ImageTaskDAO类:

      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;
              //---------------------------------------------------
          }
      
      }
      

      【讨论】:

      • jep... 可以。但是我更喜欢这个库,因为它只有 1 行没有 forloop 的代码。不过答案很好!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      • 1970-01-01
      • 2018-07-02
      • 1970-01-01
      相关资源
      最近更新 更多