原版程序出处未知,不知道是谁写的了,我在原有的基础上现在做一些改进优化
1.增加线程池功能,限制通知下载的线程数,
但是还有一些缺陷, 1.缓存的清理,大量图片之后的缓存策略,比如缓存太多之后,清理一些使用次数比较少的缓存图片 2.对于同一张图片,如果还没存在图片,那么在同一时间可以开启很多个对这张图片的下载任务,此处可以继续优化,后面有时间了再做了
public class AsyncImageLoader { private static final String TAG = "AsyncImageLoader"; private ThreadPoolExecutor mPoolExecutor; private HashMap> imageCache; private Handler mMainThreadHandler; /** * 创建一个异步图片加载器,默认最大5个工作线程,最大等待队列20 */ public AsyncImageLoader() { this(5, 20); } /** * 创建一个异步图片加载器,当等待下载的图片超过设置的最大等待数量之后,会从等待队列中放弃一个最早加入队列的任务 * * @param maxPoolSize 最大工作线程数 * @param queueSize 最大等待数 */ public AsyncImageLoader(int maxPoolSize, int queueSize) { this(2, maxPoolSize, 3, TimeUnit.SECONDS, new LinkedBlockingQueue (queueSize), new ThreadPoolExecutor.DiscardOldestPolicy()); } /** * 自定义线程池的加载器,请参考:{@link ThreadPoolExecutor} * * @param corePoolSize * @param maximumPoolSize * @param keepAliveTime * @param unit * @param workQueue * @param handler */ public AsyncImageLoader(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler) { imageCache = new HashMap >(); mPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); mMainThreadHandler = new Handler(Looper.getMainLooper()); } /** * 异步加载一张图片 * * @param imageUrl * @param imageCallback */ public void loadDrawable(final String imageUrl, final ImageCallback imageCallback) { if (imageCache.containsKey(imageUrl)) { SoftReference softReference = imageCache.get(imageUrl); Drawable drawable = softReference.get(); if (drawable != null) { LogUtils.d(TAG, "load image from cache url:" + imageUrl); imageCallback.onLoaded(drawable); return; } } LoadImageTask task = new LoadImageTask(imageUrl, this, mMainThreadHandler, imageCallback); mPoolExecutor.execute(task); } /** * 停止线程池运行,停止之后,将不能在继续调用 {@link #loadDrawable(String, ImageCallback)} */ public void shutdown() { mPoolExecutor.shutdown(); imageCache.clear(); } private void cache(String url, Drawable drawable) { imageCache.put(url, new SoftReference (drawable)); } /** * 下载任务 * */ private static final class LoadImageTask implements Runnable { private Handler mHandler; private ImageCallback mCallback; private AsyncImageLoader mLoader; private String mPath; /** * @param imgPath 要下载的图片地址 * @param loader 图片加载器 * @param handler 主线程Handler * @param imageCallback 图片加载回调 */ public LoadImageTask(String imgPath, AsyncImageLoader loader, Handler handler, ImageCallback imageCallback) { LogUtils.d(TAG, "start a task for load image:" + imgPath); this.mHandler = handler; this.mPath = imgPath; this.mLoader = loader; this.mCallback = imageCallback; } @Override public void run() { URL url; InputStream is = null; try { url = new URL(mPath); URLConnection conn = url.openConnection(); conn.connect(); is = conn.getInputStream(); final Drawable drawable = Drawable.createFromStream(is, "src"); mLoader.cache(mPath, drawable); mHandler.post(new Runnable() { @Override public void run() { LogUtils.d(TAG, "load image success:" + mPath); mCallback.onLoaded(drawable); } }); } catch (final Exception e) { LogUtils.e(TAG, e.getMessage() + "", e); mHandler.post(new Runnable() { @Override public void run() { LogUtils.d(TAG, "load image failed:" + mPath); mCallback.onError(e); } }); } } } /** * 回调接口,在主线程中运行 * */ public static interface ImageCallback { /** * 加载成功 * * @param imageDrawable 下载下来的图片 */ public void onLoaded(Drawable drawable); /** * 加载失败 * * @param e 异常 */ public void onError(Exception e); }}