排球图像加载器ConcurrentModificationException [英] Volley Image Loader ConcurrentModificationException

查看:59
本文介绍了排球图像加载器ConcurrentModificationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Volley Image loader从服务器将图像加载到我的项目中.但是在某些情况下,我会收到以下错误,并且应用程序崩溃.

I am using volley image loader for loading image on my project from server. But in some cases i am getting the following error and application crashes.

            java.util.ConcurrentModificationException
          at java.util.LinkedList$LinkIterator.next(LinkedList.java:124)
          at com.android.volley.toolbox.ImageLoader$4.run(ImageLoader.java:440)
          at android.os.Handler.handleCallback(Handler.java:739)
          at android.os.Handler.dispatchMessage(Handler.java:95)
          at android.os.Looper.loop(Looper.java:135)
          at android.app.ActivityThread.main(ActivityThread.java:5343)
          at java.lang.reflect.Method.invoke(Native Method)
          at java.lang.reflect.Method.invoke(Method.java:372)
          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

我找不到错误的原因和解决方案.请帮助我.

I can't find reason for the error and the solution for this. Please help me.

Global.java

Global.java

import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
import com.example.volley.LruBitmapCache;
import java.util.HashMap;
public class Global extends Application{
    public static final String TAG = Global.class.getSimpleName();
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Global mInstance;
    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }
    public static synchronized Global getInstance() {
        return mInstance;
    }
    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
        return mRequestQueue;
    }
    public ImageLoader getImageLoader() {
        getRequestQueue();
        if (mImageLoader == null) {
            mImageLoader = new ImageLoader(this.mRequestQueue,new LruBitmapCache());
        }
        return this.mImageLoader;
    }
    public <T> void addToRequestQueue(Request<T> req, String tag) {
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }
    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

LruBitmapCache.java

LruBitmapCache.java

import com.android.volley.toolbox.ImageLoader.ImageCache;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

public class LruBitmapCache extends LruCache<String, Bitmap> implements ImageCache {
    public static int getDefaultLruCacheSize() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;

        return cacheSize;
    }

    public LruBitmapCache() {
        this(getDefaultLruCacheSize());
    }

    public LruBitmapCache(int sizeInKiloBytes) {
        super(sizeInKiloBytes);
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getRowBytes() * value.getHeight() / 1024;
    }

    @Override
    public Bitmap getBitmap(String url) {
        return get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        put(url, bitmap);
    }
}

将图片加载到网络视图中的代码

Code to loading image into network view

ImageLoader myLoader = Global.getInstance().getImageLoader();
networkImageView.setImageUrl(thumbnailURL, myLoader);
myLoader.get(thumbnailURL, new ImageLoader.ImageListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        //Set Error image
    }
    @Override
    public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
        if (response.getBitmap() != null) {
            //Set BitMap
        }
        else{
            //Set Loading image
        }
    }
});

我的服装网络视图图像视图侦听器

My Costume network view image view listener

public class NetworkImageViewListener {

    private final String TAG_THUMBNAIL_ERROR = "THUMBNAIL_ERROR";
    private final String TAG_THUMBNAIL_RECEIVED = "THUMBNAIL_RECEIVED";

    private String TAG = getClass().getSimpleName();


    private boolean original_image_loaded = false;
    public void loadImage(final Context context,final String url,final NetworkImageView networkImageView, final int approx_width, final int approx_height,final boolean thumbnail, final ProgressBar progressBar, final boolean is_Store){
        networkImageView.setAdjustViewBounds(true);
        final int picture_not_found = R.drawable.ic_profile_picture_not_found;
        final int picture_not_loaded = R.drawable.ic_profile_picture_not_loaded;

        if (url != null && !url.equals("null")&& !url.equals("NULL")&& !url.equals("")) {
            final String originalURL = getImageUrl(url, approx_width, approx_height);

            final Bitmap cacheImage = getCacheImage(context, originalURL);
            if (cacheImage==null) {

                if(progressBar!=null){
                    progressBar.setVisibility(View.VISIBLE);
                }
                if (thumbnail) {
                    final String thumbnailURL = getImageThumbnailUrl(url, approx_width, approx_height);

                    ImageLoader thumbnailLoader = Global.getInstance().getImageLoader();
                    networkImageView.setImageUrl(thumbnailURL, thumbnailLoader);
                    thumbnailLoader.get(thumbnailURL, new ImageLoader.ImageListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            if(progressBar==null){
                                networkImageView.setImageResource(picture_not_found);
                            }
                            networkImageView.setTag(TAG_THUMBNAIL_ERROR);
                            load_Original(context, originalURL, networkImageView, progressBar, is_Store, picture_not_loaded);
                        }
                        @Override
                        public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
                            if (response.getBitmap() != null) {
                                networkImageView.setImageBitmap(response.getBitmap());
                                networkImageView.setTag(TAG_THUMBNAIL_RECEIVED);
                                load_Original(context, originalURL, networkImageView, progressBar, is_Store, picture_not_loaded);
                            } else if (progressBar==null) {
                                networkImageView.setImageResource(picture_not_found);
                            }
                        }
                    });
                }
                else{
                    load_Original(context,originalURL,networkImageView,progressBar,is_Store,picture_not_loaded);
                }
            } else {
                networkImageView.setImageBitmap(cacheImage);
            }
        } else {
            networkImageView.setImageResource(picture_not_found);
        }
    }
    private void load_Original(final Context context,final String originalURL,final NetworkImageView networkImageView, final ProgressBar progressBar, final boolean is_Store,final int picture_not_loaded){
        final Drawable temp = networkImageView.getDrawable();
        final String imageviewTag = (String) networkImageView.getTag();
        ImageLoader imageLoader = Global.getInstance().getImageLoader();
        networkImageView.setImageUrl(originalURL, imageLoader);
        imageLoader.get(originalURL, new ImageLoader.ImageListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (progressBar != null) {
                    progressBar.setVisibility(View.GONE);
                }
                if (temp != null && imageviewTag != null && !imageviewTag.equals(TAG_THUMBNAIL_ERROR)) {
                    networkImageView.setImageDrawable(temp);
                } else if (temp != null && imageviewTag != null && imageviewTag.equals(TAG_THUMBNAIL_RECEIVED)) {
                    networkImageView.setImageDrawable(temp);
                } else {
                    networkImageView.setImageResource(picture_not_loaded);
                }
            }

            @Override
            public void onResponse(ImageLoader.ImageContainer response, boolean shouldAnimate) {
                if (response.getBitmap() != null) {
                    if (progressBar != null) {
                        progressBar.setVisibility(View.GONE);
                    }
                    networkImageView.setImageBitmap(response.getBitmap());
                    if (is_Store) {
                        setCacheImage(context, originalURL, response.getBitmap());
                    }
                } else {
                    networkImageView.setImageDrawable(temp);
                }
            }
        });
    }

    private static String getImageUrl(String url, int aprox_width, int aprox_height){
        int index = url.lastIndexOf('/');
        String path = url.substring(0, index);
        String file_name =  url.substring(index + 1);
        String result = path+"/"+aprox_width+"/"+aprox_height+"/"+file_name;
        return result;
    }

    private static String getImageThumbnailUrl(String url, int approx_width, int aprox_height){
        int index = url.lastIndexOf('/');
        String path = url.substring(0, index);
        String file_name =  url.substring(index + 1);
        String result = path+"/"+approx_width+"/"+aprox_height+"/tbnil"+"/"+file_name;
        return result;
    }

    private String profile_picture_folder_name = "PP";
    private void setCacheImage(Context context, String url, Bitmap bitmap){
        try {
            if (!getCacheDirectory(context).equals("")) {
                String filename = getFileName(url);
                File folder = new File(getCacheDirectory(context)+"/"+profile_picture_folder_name+"/");
                if (!folder.exists()) {
                    folder.mkdir();
                }
                if (folder.exists()) {
                    File dest = new File(folder, filename);
                    FileOutputStream out = new FileOutputStream(dest);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 40, out);
                    out.flush();
                    out.close();
                }
            }
        } catch (Exception e) {
            Log.developer(TAG,e.getMessage());
        }
    }
    private Bitmap getCacheImage(Context context,String url){
        try {
            if (!getCacheDirectory(context).equals("")) {
                String filename = getFileName(url);
                File folder = new File(getCacheDirectory(context)+"/"+profile_picture_folder_name+"/");
                if (folder.exists()) {
                    FileInputStream fis = null;
                    File imageFile = new File(folder, filename);
                    if (imageFile.exists()) {
                        fis = new FileInputStream(imageFile);
                        return BitmapFactory.decodeStream(fis);
                    }
                }
            }
        } catch (FileNotFoundException e) {
            Log.developer(TAG, e.getMessage());
        }
        return null;
    }
    private String getCacheDirectory(Context context){
        String cachePath="";
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) {
            if (context.getExternalCacheDir() != null && context.getExternalCacheDir().exists()) {
                cachePath = context.getExternalCacheDir().getPath(); // most likely your null value
            }
            else if (context.getCacheDir() != null && context.getCacheDir().exists()) {
                cachePath = context.getCacheDir().getPath();
            }
        } else {
            if (context.getCacheDir() != null && context.getCacheDir().exists()) {
                cachePath = context.getCacheDir().getPath();
            }
        }
        return cachePath;
    }

    public String getFileName(String urlStr) {
        return urlStr.substring(urlStr.lastIndexOf('/') + 1, urlStr.length());
    }
}

推荐答案

您必须实现两个ImageLoader,一个用于缩略图,另一个用于全分辨率图像. 修改您的RequestQueue单例,如下所示:

You have to implement two ImageLoaders, one for the thumbnails and another one for the full-res images. Modify your RequestQueue singleton as follows:

//..
private ImageLoader mImageLoader;
private ImageLoader mThumbLoader;
//...
// Then in constructor
mThumbLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() { ... });
mImageLoader = new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() { ... });

// And then you build two getters
protected ImageLoader getImageLoader() {
    return mImageLoader;
}

protected ImageLoader getThumbLoader() {
    return mThumbLoader;
}

如果为缩略图调用mThumbLoader,为完整分辨率图像调用mImageLoader,它将正常工作.

If you invoke the mThumbLoader for the thumbnails and mImageLoader for the full res images it will work fine.

这篇关于排球图像加载器ConcurrentModificationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆