使用Volley框架的ImageLoader加载大量网络图片的问题

来源:互联网 发布:小黑鱼网络 编辑:程序博客网 时间:2024/04/29 22:56

使用volley框架来加载大量图片时,listView在快速滑动列表时,会发现滑动到列表后面时,图片如果稍微过大,加载会很慢,感觉有很长的等待时间,笔者分析到的原因,volley加载图片的类ImageLoader,虽然做了很多优化,但是在快速滑动列表时,每滑动到一个新的图片加载,就会产生一个新的ImageRequest 进入mRequestQueue请求队列中,后面请求的ImageRequest对象就需要等待前面的ImageRequest请求完毕,才能请求后面的图片。所以有时就会感觉很慢的原因。

笔者对volley的ImageLoader稍微改造了一下 增加一个HashMap<String, String> keymap = new HashMap<String, String>(); 用于记录listView在滑动记录视图ImageView对应的ImageRequest,

修改get方法的参数 String listkey;

public ImageContainer get(String requestUrl, final String listkey,
                              ImageListener imageListener, int maxWidth, int maxHeight) {
        // only fulfill requests that were initiated from the main thread.
        throwIfNotOnMainThread();
        final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight);
        // Try to look up the request in the cache of remote images.
        Bitmap cachedBitmap = mCache.getBitmap(cacheKey);
        if (cachedBitmap != null) {
            // Return the cached bitmap.
            ImageContainer container = new ImageContainer(cachedBitmap,
                    requestUrl, null, null, null);
            imageListener.onResponse(container, true);
            return container;
        }
        // The bitmap did not exist in the cache, fetch it!
        ImageContainer imageContainer = new ImageContainer(null, requestUrl,
                cacheKey, imageListener, listkey);

        // Update the caller to let them know that they should use the default
        // bitmap.
        imageListener.onResponse(imageContainer, true);


        // Check to see if a request is already in-flight.
        BatchedImageRequest request = mInFlightRequests.get(cacheKey);

        if (request != null) {
            // If it is, add this request to the list of listeners.
            request.addContainer(imageContainer);
            return imageContainer;
        }


      //如果加载的imageView的视图有ImageRequest,目前不需要去加载cancel掉,给下一个ImageRequest去加载
        if (listkey != null) {
            String keyvalue = keymap.get(listkey);
            BatchedImageRequest temprequest = mInFlightRequests.get(keyvalue);
            if (temprequest != null) {
                temprequest.mRequest.cancel();
                mInFlightRequests.remove(keyvalue);
                keymap.remove(listkey);
            }
        }



        // The request is not already in flight. Send the new request to the
        // network and
        // track it.
        Request<?> newRequest = new ImageRequest(requestUrl,
                new Listener<Bitmap>() {
                    @Override
                    public void onResponse(Bitmap response) {
                        onGetImageSuccess(cacheKey, listkey, response);
                    }
                }, maxWidth, maxHeight, Config.RGB_565, new ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                onGetImageError(cacheKey, listkey,error);
            }
        });
        mRequestQueue.add(newRequest);
        mInFlightRequests.put(cacheKey, new BatchedImageRequest(newRequest,
                imageContainer));

       //如果listkey 不为空保存  BatchedImageRequest的cacheKey
        if (listkey != null) {
            keymap.put(listkey, cacheKey);
        }


        return imageContainer;
    }

当然在ImageRequest请求加载图片完成后 mInFlightRequests.remove(cacheKey); 要调用 keymap.remove(listkey);

对原有的get方法也要做很多相应的重载,只要有需要列表加载图片时才需要参数listkey

在适配器使用时Listkey的参数使用imageView.hashCode()+"",

1 0
原创粉丝点击