问题
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.
回答1:
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):
Reduce thread pool size in configuration (.threadPoolSize(...)). 1 - 5 is recommended.
Use
.bitmapConfig(Bitmap.Config.RGB_565)
in display options. Bitmaps inRGB_565
consume 2 times less memory than inARGB_8888
.Use
.memoryCache(new WeakMemoryCache())
in configuration or disable caching in memory at all in display options (don't call .cacheInMemory()).Use
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
in display options. Or try.imageScaleType(ImageScaleType.EXACTLY)
.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
回答2:
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.
回答3:
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();
来源:https://stackoverflow.com/questions/17211154/universal-image-loader-uil-nostra-out-of-memory-error