Android Volley give me an outOfMemory exception
Asked Answered
H

3

10

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)
Hanshansard answered 10/6, 2013 at 16:59 Comment(0)
H
5

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?

Hanshansard answered 16/7, 2013 at 14:34 Comment(8)
I used your solution but it didn't solve my problem: #17991828 . Can You help me?Kraul
I don't think this solves an OOM error, this is just a way to keep bitmaps in app memory for faster access. See: #5762047Waterworks
yeah sure @Kraul Past a like of your questation here.. ThanksHanshansard
@Waterworks - Right, be sure that you are keep volley queue and loader as application level.Hanshansard
@Waterworks - but in my opinion Volley should handle OOM itself. Am I wrong? I initialize Volley queue (Volley.newRequestQueue) and ImageLoader inside Application class.Kraul
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)Waterworks
yeah might be, i haven't tested in older devices or vmHanshansard
@Waterworks - 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.Kraul
T
0

I don't know how your ImageLoader is implemented, but it probably loads a Bitmap. Try to set the following BitmapOption: inPurgeable to true while generating the bitmap. That way, the bitmap memory will be cleaned when you are getting low on memory.

Look at this question: Why would I ever NOT use BitmapFactory's inPurgeable option?

Tenerife answered 10/6, 2013 at 17:3 Comment(1)
ImageLoader is implemented by volley itself, thanks for the ans :)Hanshansard
U
0

I am not sure how you implemented swipe view. But in most implementations (like viewpager) it will cache 3 or more items. So you don't really need to provide the LRUCache to volley.

Just remove the code for imageCache and you will see improvements in memory usage.

Upbuild answered 13/7, 2013 at 7:35 Comment(1)
actually volley only provides disk caching we still need to set memory cache to the volley, thanks for the ans :)Hanshansard

© 2022 - 2024 — McMap. All rights reserved.