| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
jopen
10年前发布

图片批量下载一个Android工具类

项目中用到的,要求一次下载30张图片。开始时使用谷歌bitmap fun中提供的ImageFetcher来下载,但是发现一个蛋疼无比现象,图片总是莫名其妙的少几张。

   排除了图片地址存在无效链接外,怀疑是并发下载线程个数太多,线程池满了以后,使用抛弃策略将以前的下载线程抛弃了。

   求人不如求己,自己写一个吧。

   在这里使用线程池,支持并发下载。线程池可以自己选择,使用 newSingleThreadExecutor,newFixedThreadPool,newCachedThreadPool中的任意一种。使用 时,自己实现监听器,当监听下载个数与url集合的个数相同时,会回调监听器的onSuccess()方法。

   源码如下,希望大家指正

import java.io.BufferedInputStream;  import java.io.BufferedOutputStream;  import java.io.File;  import java.io.FileOutputStream;  import java.io.IOException;  import java.io.InputStream;  import java.io.UnsupportedEncodingException;  import java.net.HttpURLConnection;  import java.net.URL;  import java.net.URLEncoder;  import java.util.List;  import java.util.concurrent.ExecutorService;  import java.util.concurrent.Executors;  import java.util.concurrent.RejectedExecutionException;  import android.util.Log;     /**   * 批量图片下载类 无需与界面交互的下载类   *   * @Description:   *   * @author- liubing   * @create- 2013-5 -6   * @modify by:   * @modify- time   */  public class DownloadService {       private static String TAG = "DownloadService" ;       public static final int IO_BUFFER_SIZE = 8 * 1024;       private static final String CACHE_FILENAME_PREFIX = "cache_";       private static ExecutorService SINGLE_TASK_EXECUTOR = null;       private static ExecutorService LIMITED_TASK_EXECUTOR = null;       private static final ExecutorService FULL_TASK_EXECUTOR = null;       private static final ExecutorService DEFAULT_TASK_EXECUTOR ;       private static Object lock = new Object();       static {             // SINGLE_TASK_EXECUTOR = (ExecutorService)             // Executors.newSingleThreadExecutor();             LIMITED_TASK_EXECUTOR = (ExecutorService) Executors                     . newFixedThreadPool(1);             // FULL_TASK_EXECUTOR = (ExecutorService)             // Executors.newCachedThreadPool();             DEFAULT_TASK_EXECUTOR = LIMITED_TASK_EXECUTOR ;       };       // 下载状态监听,提供回调       DownloadStateListener listener;       // 下载目录       private String downloadPath;          // 下载链接集合       private List<String> listURL;       // 下载个数       private int size = 0;          // 下载完成回调接口       public interface DownloadStateListener {             public void onFinish();                public void onFailed();       }          public DownloadService(String downloadPath, List<String> listURL,                DownloadStateListener listener) {             this.downloadPath = downloadPath;             this.listURL = listURL;             this.listener = listener;       }          /**        * 暂未提供设置        */       public void setDefaultExecutor() {          }          /**        * 开始下载        */       public void startDownload() {             // 首先检测path是否存在            File downloadDirectory = new File(downloadPath );             if (!downloadDirectory.exists()) {                downloadDirectory.mkdirs();            }                for (final String url : listURL) {                 //捕获线程池拒绝执行异常                 try {                      // 线程放入线程池                      DEFAULT_TASK_EXECUTOR.execute(new Runnable() {                              @Override                           public void run() {                               downloadBitmap(url);                          }                     });                } catch (RejectedExecutionException e) {                     e.printStackTrace();                     Log. e(TAG, "thread pool rejected error");                      listener.onFailed();                } catch (Exception e) {                     e.printStackTrace();                      listener.onFailed();                }               }          }          /**        * 下载图片        *        * @param urlString        * @return        */       private File downloadBitmap(String urlString) {            String fileName = urlString;             // 图片命名方式             final File cacheFile = new File(createFilePath(new File(                      downloadPath), fileName));               HttpURLConnection urlConnection = null;            BufferedOutputStream out = null;                try {                 final URL url = new URL(urlString);                urlConnection = (HttpURLConnection) url.openConnection();                 final InputStream in = new BufferedInputStream(                          urlConnection.getInputStream(), IO_BUFFER_SIZE);                out = new BufferedOutputStream(new FileOutputStream(cacheFile),                           IO_BUFFER_SIZE);                    int b;                 while ((b = in.read()) != -1) {                     out.write(b);                }                 // 每下载成功一个,统计一下图片个数                statDownloadNum();                 return cacheFile;               } catch (final IOException e) {                 // 有一个下载失败,则表示批量下载没有成功                Log. e(TAG, "download " + urlString + " error");                 listener.onFailed();               } finally {                 if (urlConnection != null) {                     urlConnection.disconnect();                }                 if (out != null ) {                      try {                          out.close();                     } catch (final IOException e) {                          Log. e(TAG, "Error in downloadBitmap - " + e);                     }                }            }                return null ;       }          /**        * Creates a constant cache file path given a target cache directory and an        * image key.        *        * @param cacheDir        * @param key        * @return        */       public static String createFilePath(File cacheDir, String key) {             try {                 // Use URLEncoder to ensure we have a valid filename, a tad hacky                 // but it will do for                 // this example                 return cacheDir.getAbsolutePath() + File.separator + CACHE_FILENAME_PREFIX                          + URLEncoder.encode(key.replace("*", ""), "UTF-8" );            } catch (final UnsupportedEncodingException e) {                Log. e(TAG, "createFilePath - " + e);            }                return null ;       }             /**        * 统计下载个数        */       private void statDownloadNum() {             synchronized (lock ) {                 size++;                 if (size == listURL .size()) {                     Log. d(TAG, "download finished total " + size);                      // 释放资源                      DEFAULT_TASK_EXECUTOR.shutdownNow();                      // 如果下载成功的个数与列表中 url个数一致,说明下载成功                      listener.onFinish(); // 下载成功回调                }            }       }  }

使用方法如下:

new DownloadService( "/mnt/sdcard/test", listUrl, new DownloadStateListener() {                                  @Override                 public void onFinish() {                      //图片下载成功后,实现您的代码                                      }                                  @Override                 public void onFailed() {                      //图片下载成功后,实现您的代码                                      }            }).startDownload();

原文地址: http://www.chengxuyuans.com/Android/62528.html