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)
Sagar Maiyad
  • 12,655
  • 9
  • 63
  • 99
AJit
  • 1,283
  • 1
  • 13
  • 34

3 Answers3

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?

Community
  • 1
  • 1
AJit
  • 1,283
  • 1
  • 13
  • 34
  • 1
    I used your solution but it didn't solve my problem: http://stackoverflow.com/questions/17991328/how-to-deal-with-outofmemory-exception . Can You help me? – Ziem Aug 03 '13 at 10:25
  • I don't think this solves an OOM error, this is just a way to keep bitmaps in app memory for faster access. See: http://stackoverflow.com/questions/5761547/out-of-memory-errors-occur-with-a-high-heap-size-but-low-allocated-size-why – pjco Aug 15 '13 at 18:17
  • yeah sure @Ziem Past a like of your questation here.. Thanks – AJit Aug 26 '13 at 17:05
  • 1
    @pjco - Right, be sure that you are keep volley queue and loader as application level. – AJit Aug 26 '13 at 17:08
  • @pjco - but in my opinion Volley should handle OOM itself. Am I wrong? I initialize Volley queue (Volley.newRequestQueue) and ImageLoader inside Application class. – Ziem Aug 26 '13 at 18:16
  • 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) – pjco Aug 26 '13 at 18:39
  • yeah might be, i haven't tested in older devices or vm – AJit Aug 26 '13 at 18:55
  • @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. – Ziem Aug 26 '13 at 19:32
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?

Community
  • 1
  • 1
Sebastian Breit
  • 6,137
  • 1
  • 35
  • 53
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.

Mandar Limaye
  • 1,900
  • 16
  • 24
  • actually volley only provides disk caching we still need to set memory cache to the volley, thanks for the ans :) – AJit Jul 16 '13 at 14:32