Android Volley give me an outOfMemory exception

11,040

i did fix this to provide proper cache to the BitmapLruCache insted of LruCache

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

    return cacheSize;
}

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

public BitmapLruCache(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);
}

}

here is the link: Android Volley ImageLoader - BitmapLruCache parameter?

Share:
11,040
AJit
Author by

AJit

Android, iOS &amp; Mac Developer since 2nd jan 2012

Updated on July 20, 2022

Comments

  • AJit
    AJit almost 2 years

    I am using volley to showing images in horizontal swipe view from the server, but my images are quite large that's way i am getting an exception of out of memory

    Below is my volley class:

    public class Volley{
    
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    
    public Volley(Context ctx) {
        Log.v("Volley", "Volley onCreate");
        mRequestQueue = com.android.volley.toolbox.Volley.newRequestQueue(ctx);
    
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;
    
        ImageLoader.ImageCache imageCache = new ImageLoader.ImageCache() {
            LruCache<String, Bitmap> imageCache = new LruCache<String, Bitmap>(cacheSize);
    
            @Override
            public void putBitmap(String key, Bitmap value) {
                imageCache.put(key, value);
            }
    
            @Override
            public Bitmap getBitmap(String key) {
                return imageCache.get(key);
            }
        };
    
        mImageLoader = new ImageLoader(mRequestQueue, imageCache);
    
    }
    
    public void clear(Context ctx) {
        mRequestQueue.cancelAll(ctx);
        mImageLoader = null;
        mRequestQueue = null;
    }
    
    public RequestQueue getRequestQueue() {
        return mRequestQueue;
    }
    
    public ImageLoader getImageLoader() {
        return mImageLoader;
    }}
    

    Image loader code:

    image.setImageUrl(imagePhoto.url, getVolley(getContext()).getImageLoader());
    
    public Volley getVolley(Context ctx) {
        if(mVolley == null) {
            mVolley = new Volley(getContext());
        }
        return mVolley;
    }
    

    Exception:

    > 06-10 22:14:27.462: E/AndroidRuntime(10060): FATAL EXCEPTION: Thread-29479
    06-10 22:14:27.462: E/AndroidRuntime(10060): java.lang.OutOfMemoryError
    06-10 22:14:27.462: E/AndroidRuntime(10060):    at com.android.volley.toolbox.ByteArrayPool.getBuf(ByteArrayPool.java:101)
    06-10 22:14:27.462: E/AndroidRuntime(10060):    at com.android.volley.toolbox.PoolingByteArrayOutputStream.<init>(PoolingByteArrayOutputStream.java:53)
    06-10 22:14:27.462: E/AndroidRuntime(10060):    at com.android.volley.toolbox.BasicNetwork.entityToBytes(BasicNetwork.java:202)
    06-10 22:14:27.462: E/AndroidRuntime(10060):    at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:104)
    06-10 22:14:27.462: E/AndroidRuntime(10060):    at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:105)
    
  • AJit
    AJit about 11 years
    ImageLoader is implemented by volley itself, thanks for the ans :)
  • AJit
    AJit almost 11 years
    actually volley only provides disk caching we still need to set memory cache to the volley, thanks for the ans :)
  • Ziem
    Ziem almost 11 years
    I used your solution but it didn't solve my problem: stackoverflow.com/questions/17991328/… . Can You help me?
  • pjco
    pjco almost 11 years
    I don't think this solves an OOM error, this is just a way to keep bitmaps in app memory for faster access. See: stackoverflow.com/questions/5761547/…
  • AJit
    AJit almost 11 years
    yeah sure @Ziem Past a like of your questation here.. Thanks
  • AJit
    AJit almost 11 years
    @pjco - Right, be sure that you are keep volley queue and loader as application level.
  • Ziem
    Ziem almost 11 years
    @pjco - but in my opinion Volley should handle OOM itself. Am I wrong? I initialize Volley queue (Volley.newRequestQueue) and ImageLoader inside Application class.
  • pjco
    pjco almost 11 years
    It should, and it does catch the error. However, keeping the cache global and/or a bit on the conservative side is always good. But the above technique is memory caching not controlled by Volley, and would use memory separate to volley's decoding memory. I think the problem is mostly with older devices that didn't have as much control over the image decoding process (so you see things like "vm won't let us allocate..." in the volley logcat)
  • AJit
    AJit almost 11 years
    yeah might be, i haven't tested in older devices or vm
  • Ziem
    Ziem almost 11 years
    @pjco - Thanks. You are right, it seems that OOM occurs on older devices (e.g. HTC Desire). Another question: how can I prevent OOM exception when using Volley? All my network operations, bitmap processing etc. is handled by Volley.