5

I am using UIL to load remote images and fill up Fragments in FragmentStatePagerAdapter. I have read readme and usual errors but I can't solve out this bug.

Here is the config:

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
    .threadPoolSize(1)
    .build();
    ImageLoader.getInstance().init(config);

Here is where i display my images:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {


    ImageLoader imgLoader = ImageLoader.getInstance();

    DisplayImageOptions options = new DisplayImageOptions.Builder()
    .showStubImage(R.drawable.loading)
    .cacheOnDisc()
    .resetViewBeforeLoading()
    .bitmapConfig(Bitmap.Config.RGB_565)
    .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
    .build();

    imgLoader.displayImage(this.contentImage, this.imgView, options);

    return layout;
}

And here is where I destroy my fragments in the adapter:

public void destroyItem(ViewGroup container, int position, Object object) {
    if (position >= getCount()) {
        container.removeAllViews();
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }
}

and finally here is the exception I get:

{
06-20 12:09:24.877: E/dalvikvm-heap(17043): Out of memory on a 6345504-byte allocation.
06-20 12:09:24.877: I/dalvikvm(17043): "pool-1-thread-1" prio=4 tid=16 RUNNABLE
06-20 12:09:24.877: I/dalvikvm(17043):   | group="main" sCount=0 dsCount=0 obj=0x42593a48 self=0x6367e778
06-20 12:09:24.887: I/dalvikvm(17043):   | sysTid=17091 nice=10 sched=0/0 cgrp=apps/bg_non_interactive handle=1667639656
06-20 12:09:24.887: I/dalvikvm(17043):   | state=R schedstat=( 4021618000 2254117000 18267 ) utm=341 stm=61 core=0
06-20 12:09:24.887: I/dalvikvm(17043):   #00  pc 00074350  /system/lib/libdvm.so (dvmDumpNativeStack(DebugOutputTarget const*, int)+35)
06-20 12:09:24.887: I/dalvikvm(17043):   #01  pc 00062afe  /system/lib/libdvm.so (dvmDumpThreadEx(DebugOutputTarget const*, Thread*, bool)+557)
06-20 12:09:24.887: I/dalvikvm(17043):   #02  pc 00062bae  /system/lib/libdvm.so (dvmDumpThread(Thread*, bool)+25)
06-20 12:09:24.887: I/dalvikvm(17043):   #03  pc 000298ec  /system/lib/libdvm.so (dvmMalloc(unsigned int, int)+584)
06-20 12:09:24.887: I/dalvikvm(17043):   #04  pc 0007fdfe  /system/lib/libdvm.so (dvmAllocPrimitiveArray(char, unsigned int, int)+93)
06-20 12:09:24.887: I/dalvikvm(17043):   #05  pc 0005357e  /system/lib/libdvm.so
06-20 12:09:24.887: I/dalvikvm(17043):   #06  pc 000798e0  /system/lib/libandroid_runtime.so (GraphicsJNI::allocateJavaPixelRef(_JNIEnv*, SkBitmap*, SkColorTable*)+67)
06-20 12:09:24.887: I/dalvikvm(17043):   #07  pc 000799ae  /system/lib/libandroid_runtime.so (JavaPixelAllocator::allocPixelRef(SkBitmap*, SkColorTable*)+45)
06-20 12:09:24.887: I/dalvikvm(17043):   #08  pc 0004aa18  /system/lib/libskia.so (SkBitmap::allocPixels(SkBitmap::Allocator*, SkColorTable*)+56)
06-20 12:09:24.887: I/dalvikvm(17043):   #09  pc 000cd848  /system/lib/libskia.so (SkPNGImageDecoder::onDecode(SkStream*, SkBitmap*, SkImageDecoder::Mode)+404)
06-20 12:09:24.887: I/dalvikvm(17043):   #10  pc 000c9504  /system/lib/libskia.so (SkImageDecoder::decode(SkStream*, SkBitmap*, SkBitmap::Config, SkImageDecoder::Mode, bool)+168)
06-20 12:09:24.887: I/dalvikvm(17043):   #11  pc 00075a08  /system/lib/libandroid_runtime.so
06-20 12:09:24.887: I/dalvikvm(17043):   #12  pc 000762ac  /system/lib/libandroid_runtime.so
06-20 12:09:24.887: I/dalvikvm(17043):   #13  pc 0001dd8c  /system/lib/libdvm.so (dvmPlatformInvoke+112)
06-20 12:09:24.887: I/dalvikvm(17043):   #14  pc 0005a6e2  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+165)
06-20 12:09:24.887: I/dalvikvm(17043):   #15  pc 000271a0  /system/lib/libdvm.so
06-20 12:09:24.887: I/dalvikvm(17043):   #16  pc 0002b898  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
06-20 12:09:24.887: I/dalvikvm(17043):   #17  pc 00073d2c  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+563)
06-20 12:09:24.887: I/dalvikvm(17043):   #18  pc 00073e04  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+19)
06-20 12:09:24.887: I/dalvikvm(17043):   #19  pc 000640f4  /system/lib/libdvm.so
06-20 12:09:24.887: I/dalvikvm(17043):   #20  pc 0000dcfc  /system/lib/libc.so (__thread_entry+124)
06-20 12:09:24.887: I/dalvikvm(17043):   #21  pc 0000d8d0  /system/lib/libc.so (pthread_create+172)
06-20 12:09:24.887: I/dalvikvm(17043):   at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
06-20 12:09:24.887: I/dalvikvm(17043):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529)
06-20 12:09:24.887: I/dalvikvm(17043):   at com.nostra13.universalimageloader.core.ImageDecoder.decode(ImageDecoder.java:82)
06-20 12:09:24.887: I/dalvikvm(17043):   at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:270)
06-20 12:09:24.887: I/dalvikvm(17043):   at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:244)
06-20 12:09:24.887: I/dalvikvm(17043):   at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:149)
06-20 12:09:24.887: I/dalvikvm(17043):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
06-20 12:09:24.887: I/dalvikvm(17043):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
06-20 12:09:24.887: I/dalvikvm(17043):   at java.lang.Thread.run(Thread.java:856)
06-20 12:09:24.897: D/skia(17043): --- decoder->decode returned false
06-20 12:09:24.897: E/ImageLoader(17043): null
06-20 12:09:24.897: E/ImageLoader(17043): java.lang.OutOfMemoryError
06-20 12:09:24.897: E/ImageLoader(17043):   at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
06-20 12:09:24.897: E/ImageLoader(17043):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529)
06-20 12:09:24.897: E/ImageLoader(17043):   at com.nostra13.universalimageloader.core.ImageDecoder.decode(ImageDecoder.java:82)
06-20 12:09:24.897: E/ImageLoader(17043):   at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:270)
06-20 12:09:24.897: E/ImageLoader(17043):   at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:244)
06-20 12:09:24.897: E/ImageLoader(17043):   at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:149)
06-20 12:09:24.897: E/ImageLoader(17043):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
06-20 12:09:24.897: E/ImageLoader(17043):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
06-20 12:09:24.897: E/ImageLoader(17043):   at java.lang.Thread.run(Thread.java:856)
}

I don't have any idea in how to solve it. Loaded images are variable in size. They may vary from 500KB to 1.5MB.

vandus
  • 3,248
  • 3
  • 30
  • 44
Martino Lessio
  • 775
  • 1
  • 9
  • 17
  • check this might help http://stackoverflow.com/questions/16789676/caching-images-and-displaying/16978285#16978285 – Raghunandan Jun 20 '13 at 10:40

3 Answers3

12

https://github.com/nostra13/Android-Universal-Image-Loader.

From the above link

If you often get OutOfMemoryError in your app using Universal Image Loader then try next (all of them or several):

  1. Reduce thread pool size in configuration (.threadPoolSize(...)). 1 - 5 is recommended.

  2. Use .bitmapConfig(Bitmap.Config.RGB_565) in display options. Bitmaps in RGB_565 consume 2 times less memory than in ARGB_8888.

  3. Use .memoryCache(new WeakMemoryCache()) in configuration or disable caching in memory at all in display options (don't call .cacheInMemory()).

  4. Use .imageScaleType(ImageScaleType.IN_SAMPLE_INT) in display options. Or try .imageScaleType(ImageScaleType.EXACTLY).

  5. Avoid using RoundedBitmapDisplayer. It creates new Bitmap object with ARGB_8888 config for displaying during work.

Example: Modify the c.ode in the below link sticking to the above points to avoid OOM

Caching images and displaying

Community
  • 1
  • 1
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • well that's what the doc says. if the image is too large you might run into memory leaks. so the other option is to scale down the image – Raghunandan Jun 20 '13 at 10:48
  • http://stackoverflow.com/questions/15741947/android-universal-image-loader-resize-picture-before-displaing-it-in-a-view. check the answer my Nostra himself. may be this will help. – Raghunandan Jun 20 '13 at 10:52
  • @Raghunandan Hi, I have used picasso and Glide to load images.But it is throwing memory issue.In my application ,I have loading more than 200 images in homepage using recyclerview.can you give me some suggestion which library is best to avoid out of memory issue. – Stephen Sep 26 '16 at 09:12
  • @Naruto you can try Facebook's fresco. But glide is very good. – Raghunandan Sep 26 '16 at 09:37
  • @Raghunandan now I trying universal image loader..Previously I tried glide only.I followed this [link](https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en) to fix out of memory issue with glide.but couldn't fix that.did you know how to perform scaling and cache using glide to avoid memory issue? – Stephen Sep 26 '16 at 10:09
  • @Naruto you can write your own transformation and then use glide. https://github.com/bumptech/glide/wiki/Transformations – Raghunandan Sep 26 '16 at 10:25
  • @Raghunandan ok let me try that one.Thanks for suggestion – Stephen Sep 26 '16 at 10:42
4

SOLVED:

It wasnt't a UIL problem. The problem was with the page adapter. The bitmaps in the Fragments weren't handled properly by the GC and there was some indirect reference retaining them. Freeing the bitmaps explicitely solved the problem.

EDIT:

It wasn't a proper UIL problem. I was working with SupportFragment library, and this may be not properly tweaked. The trick for me was manually release every bitmap that was not on screen, but the problem should be looked at in a different way. This application uses a very large amount of WebViews, that in my opinion are evil due to fact that their memory consumption is simply silly! Adding UIL with hi-res images makes my app going OOM due to the combination of these factors.

It's a bit empirical solution, but it really works.

Martino Lessio
  • 775
  • 1
  • 9
  • 17
2

I have following configuration with disk cache. I never faced problem of OOM.

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
            YourActivity.this).threadPoolSize(5)
            .threadPriority(Thread.MIN_PRIORITY + 3)
            .denyCacheImageMultipleSizesInMemory()
            // .memoryCache(new UsingFreqLimitedMemoryCache(2000000)) // You
            // can pass your own memory cache implementation
            .memoryCacheSize(1048576 * 10)
            // 1MB=1048576 *declare 20 or more size if images are more than
            // 200
            .discCache(new UnlimitedDiscCache(cacheDir))
            // You can pass your own disc cache implementation
            // .defaultDisplayImageOptions(DisplayImageOptions.createSimple())
            .build();

To create cache dir,

File cacheDir = new File(this.getCacheDir(), "imgcachedir");
    if (!cacheDir.exists())
        cacheDir.mkdir();
Chintan Rathod
  • 25,864
  • 13
  • 83
  • 93