问题
I am handling larges images with 900 x 900
dimension. The images are displayed by a gridview implementation. There are 5 gridviews inside ViewPager's pages. The problem after 4 times of screen orientation change, I am getting out of memory error and the images starts not displaying. The
grow heap increases up to 43 mb. I posted the log cat errors. I am using Universal-image-loader.
File cacheDir = new File(getActivity().getExternalCacheDir(), "CachedImages");
if (!cacheDir.exists())
cacheDir.mkdir();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getActivity())
.threadPoolSize(5)
.threadPriority(Thread.MIN_PRIORITY + 3)
//.denyCacheImageMultipleSizesInMemory()
.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
.discCacheSize(3048576 * 20)
.memoryCache(new WeakMemoryCache())
// 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();
imageLoader.init(config);
options = new DisplayImageOptions.Builder()
//.showStubImage(icon)
//Because you reuse view for different
//images you can see a previous image in the view while new image is loading. .resetViewBeforeLoading(true
.showImageForEmptyUri(R.drawable.content_picture)
.showImageOnFail(R.drawable.content_picture)
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.bitmapConfig(Config.RGB_565)
.cacheInMemory(false)
.cacheOnDisc(true)
.resetViewBeforeLoading(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
LogCat:
10-22 18:19:25.856: E/SkWMTJdec(19464): wmt_jdec_header error : ERR_JDEC_NOT_SUPPORT_PROFILE!
10-22 18:19:26.028: I/dalvikvm-heap(19464): Clamp target GC heap from 48.663MB to 48.000MB
10-22 18:19:26.034: D/dalvikvm(19464): GC_FOR_ALLOC freed 692K, 3% free 47698K/49031K, paused 117ms, total 123ms
10-22 18:19:26.034: I/dalvikvm-heap(19464): Forcing collection of SoftReferences for 1783372-byte allocation
10-22 18:19:26.171: I/dalvikvm-heap(19464): Clamp target GC heap from 48.646MB to 48.000MB
10-22 18:19:26.176: D/dalvikvm(19464): GC_BEFORE_OOM freed 16K, 3% free 47681K/49031K, paused 140ms, total 140ms
10-22 18:19:26.176: E/dalvikvm-heap(19464): Out of memory on a 1783372-byte allocation.
10-22 18:19:26.177: I/dalvikvm(19464): "pool-182-thread-1" prio=4 tid=13 RUNNABLE
10-22 18:19:26.179: I/dalvikvm(19464): | group="main" sCount=0 dsCount=0 obj=0x41713660 self=0x5c8d92b0
10-22 18:19:26.179: I/dalvikvm(19464): | sysTid=19664 nice=10 sched=3/0 cgrp=[fopen-error:2] handle=1551184560
10-22 18:19:26.180: I/dalvikvm(19464): | schedstat=( 0 0 0 ) utm=31 stm=2 core=0
10-22 18:19:26.182: I/dalvikvm(19464): at android.graphics.Bitmap.nativeCreate(Native Method)
10-22 18:19:26.183: I/dalvikvm(19464): at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
10-22 18:19:26.189: I/dalvikvm(19464): at android.graphics.Bitmap.createBitmap(Bitmap.java:586)
10-22 18:19:26.189: I/dalvikvm(19464): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.considerExactScaleAndOrientaiton(BaseImageDecoder.java:188)
10-22 18:19:26.190: I/dalvikvm(19464): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:76)
10-22 18:19:26.192: I/dalvikvm(19464): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:305)
10-22 18:19:26.193: I/dalvikvm(19464): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:251)
10-22 18:19:26.194: I/dalvikvm(19464): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:129)
10-22 18:19:26.195: I/dalvikvm(19464): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
10-22 18:19:26.195: I/dalvikvm(19464): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
10-22 18:19:26.195: I/dalvikvm(19464): at java.lang.Thread.run(Thread.java:856)
10-22 18:19:26.197: I/View tag inside onLoadingComplete:(19464): image_item_grid_image
10-22 18:19:26.204: E/ImageLoader(19464): null
10-22 18:19:26.204: E/ImageLoader(19464): java.lang.OutOfMemoryError
10-22 18:19:26.204: E/ImageLoader(19464): at android.graphics.Bitmap.nativeCreate(Native Method)
10-22 18:19:26.204: E/ImageLoader(19464): at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
10-22 18:19:26.204: E/ImageLoader(19464): at android.graphics.Bitmap.createBitmap(Bitmap.java:586)
10-22 18:19:26.204: E/ImageLoader(19464): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.considerExactScaleAndOrientaiton(BaseImageDecoder.java:188)
10-22 18:19:26.204: E/ImageLoader(19464): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:76)
10-22 18:19:26.204: E/ImageLoader(19464): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:305)
10-22 18:19:26.204: E/ImageLoader(19464): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:251)
10-22 18:19:26.204: E/ImageLoader(19464): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:129)
10-22 18:19:26.204: E/ImageLoader(19464): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
10-22 18:19:26.204: E/ImageLoader(19464): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
10-22 18:19:26.204: E/ImageLoader(19464): at java.lang.Thread.run(Thread.java:856)
UPDATE:
@Override
public void onPause(){
super.onPause();
imageLoader.pause();
}
@Override
public void onResume(){
super.onResume();
imageLoader.resume();
}
@Override
public void onDestroy(){
super.onDestroy();
imageLoader.stop();
}
回答1:
Please edit your code to
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.content_picture)
.showImageOnFail(R.drawable.content_picture)
.resetViewBeforeLoading(false)
.delayBeforeLoading(1000)
.cacheOnDisc(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getActivity())
.discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null)
.threadPoolSize(5)
.defaultDisplayImageOptions(defaultOptions)
.denyCacheImageMultipleSizesInMemory()
.discCacheSize(50 * 1024 * 1024)
.writeDebugLogs()
.build();
ImageLoader.getInstance().init(config);
ImageLoader.getInstance().handleSlowNetwork(true);
回答2:
It looks like you have to recycle all the bitmaps. You can also call to the garbage collector like this System.gc();
Every time your app's orientation changes, it's reloading all the bitmaps again.
You could try to free memory in the onResume() which is called after the orientation change.
public void onResume(){
super.onResume();
//Clean data
}
回答3:
use following function to scale down the image,,so use result bitmap it wont rise out Of memory exception
public Bitmap scaleDownBitmap(Bitmap photo, int newHeight, Context context) {
final float densityMultiplier = context.getResources()
.getDisplayMetrics().density;
int h = (int) (newHeight * densityMultiplier);
int w = (int) (h * photo.getWidth() / ((double) photo.getHeight()));
photo = Bitmap.createScaledBitmap(photo, w, h, true);
return photo;
}
来源:https://stackoverflow.com/questions/19515303/out-of-memory-using-after-5-times-of-change-orientation