android - Volley源码中ImageLoader类的batchResponse方法的实现问题
PHPz
PHPz 2017-04-17 16:26:37
[Android讨论组]
  1. 首先,我需要说明一下,最近几天我利用空闲时间一直在研究Volley源码,并且已经在github上创建了项目,所以该问题并不是小白问题。项目地址:https://github.com/wangzhengyi/Volley。

  2. 这里我提的问题就是ImageLoader类里batchResponse方法的实现问题。

  3. 问题具体描述如下:

我很奇怪,为什么ImageLoader类里面要有一个HashMap来保存BatchedImageRequest集合呢?

    private final HashMap<String, BatchedImageRequest> mBatchedResponses =
            new HashMap<String, BatchedImageRequest>();

毕竟batchResponse是在特定的ImageRequest执行成功的回调中被调用的,调用代码如下:

    protected void onGetImageSuccess(String cacheKey, Bitmap response) {
        // 增加L1缓存的键值对.
        mCache.putBitmap(cacheKey, response);

        // 同一时间内最初的ImageRequest执行成功后,回调这段时间阻塞的相同ImageRequest对应的成功回调接口.
        BatchedImageRequest request = mInFlightRequests.remove(cacheKey);
        if (request != null) {
            request.mResponseBitmap = response;
            // 将阻塞的ImageRequest进行结果分发.
            batchResponse(cacheKey, request);
        }
    }

从上述代码可以看出,ImageRequest请求成功后,已经从mInFlightRequests中获取了对应的BatchedImageRequest对象.而同一时间被阻塞的相同的ImageRequest对应的ImageContainer都在BatchedImageRequest的mContainers集合中.
那我认为,batchResponse方法只需要遍历对应BatchedImageRequest的mContainers集合即可.
但是,ImageLoader源码中,我认为多余的构造了一个HashMap对象mBatchedResponses来保存BatchedImageRequest集合,然后在batchResponse方法中又对集合进行两层for循环各种遍历,实在是非常诡异,求指导.
诡异代码如下:

    private void batchResponse(String cacheKey, BatchedImageRequest request) {
        mBatchedResponses.put(cacheKey, request);
        if (mRunnable == null) {
            mRunnable = new Runnable() {
                @Override
                public void run() {
                    for (BatchedImageRequest bir :  mBatchedResponses.values()) {
                        for (ImageContainer container : bir.mContainers) {
                            if (container.mListener == null) {
                                continue;
                            }

                            if (bir.getError() == null) {
                                container.mBitmap = bir.mResponseBitmap;
                                container.mListener.onResponse(container, false);
                            } else {
                                container.mListener.onErrorResponse(bir.getError());
                            }
                        }
                    }
                    mBatchedResponses.clear();
                    mRunnable = null;
                }
            };
            // Post the runnable
            mHandler.postDelayed(mRunnable, 100);
        }
    }

我认为的代码实现应该是:

    private void batchResponse(String cacheKey, BatchedImageRequest request) {
        if (mRunnable == null) {
            mRunnable = new Runnable() {
                @Override
                public void run() {
                    for (ImageContainer container : request.mContainers) {
                        if (container.mListener == null) {
                            continue;
                        }

                        if (request.getError() == null) {
                            container.mBitmap = request.mResponseBitmap;
                            container.mListener.onResponse(container, false);
                        } else {
                            container.mListener.onErrorResponse(request.getError());
                        }
                    }
                    mRunnable = null;
                }
            };
            // Post the runnable
            mHandler.postDelayed(mRunnable, 100);
        }
    }
PHPz
PHPz

学习是最好的投资!

全部回复(0)
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号