AsyncImageLoader升级版,多线程异步图片加载器

原版程序出处未知,不知道是谁写的了,我在原有的基础上现在做一些改进优化

1.增加线程池功能,限制通知下载的线程数,

但是还有一些缺陷,
1.缓存的清理,大量图片之后的缓存策略,比如缓存太多之后,清理一些使用次数比较少的缓存图片
2.对于同一张图片,如果还没存在图片,那么在同一时间可以开启很多个对这张图片的下载任务,此处可以继续优化,后面有时间了再做了

public class AsyncImageLoader {
    private static final String TAG = "AsyncImageLoader";
    private ThreadPoolExecutor mPoolExecutor;
    private HashMap<String, SoftReference<Drawable>> 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<Runnable>(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<Runnable> workQueue, RejectedExecutionHandler handler) {
        imageCache = new HashMap<String, SoftReference<Drawable>>();
        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<Drawable> 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>(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);
    }
}

转载于:https://my.oschina.net/javalover/blog/172465

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值