OutofMemoryError:位图大小超过虚拟机预算(Android)

在BitmapFactory中获取一个例外。 不知道是什么问题。 (嗯,我可以猜到这个问题,但不知道为什么会发生)

 错误/ AndroidRuntime(7906):java.lang.OutOfMemoryError:位图大小超过VM预算

错误/ AndroidRuntime(7906):在android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:295) 

我的代码非常简单。 我定义了一个带有默认图像的XML布局。 我试图在SD卡上加载一个bm(​​如果存在的话)。 如果不是,则显示默认图像。 无论如何..这里是代码:

public class showpicture extends Activity { public void onCreate(Bundle savedInstanceState) { /** Remove menu/status bar **/ requestWindowFeature(Window.FEATURE_NO_TITLE); final Window win = getWindow(); win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); Bitmap bm; super.onCreate(savedInstanceState); setContentView(R.layout.showpicture); try { ImageView mImageButton = (ImageView)findViewById(R.id.displayPicture); bm = Bitmap.createScaledBitmap(BitmapFactory.decodeFile("/sdcard/dcim/Camera/20091018203339743.jpg"),100, 100, true); parkImageButton.setImageBitmap(bm); } catch (IllegalArgumentException ex) { Log.d("MYAPP",ex.getMessage()); } catch (IllegalStateException ex) { 

它失败了bm=Bitmap.createScaledBitmap任何想法? 我在论坛上做了一些研究,并指出这篇文章我只是不知道为什么它不工作。 任何帮助将是伟大的! 谢谢,

克里斯。

inSampleSize是一个很好的提示。 但是固定值往往不能正常工作,因为文件中的大型位图通常是用户文件,可以从微缩到数码相机的1200万像素。

这是一个快速而脏的加载例程。 我知道还有改进的空间,比如更好的编码循环,使用2的幂来加速解码,等等。 但是这是一个工作的开始…

 public static Bitmap loadResizedBitmap( String filename, int width, int height, boolean exact ) { Bitmap bitmap = null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile( filename, options ); if ( options.outHeight > 0 && options.outWidth > 0 ) { options.inJustDecodeBounds = false; options.inSampleSize = 2; while ( options.outWidth / options.inSampleSize > width && options.outHeight / options.inSampleSize > height ) { options.inSampleSize++; } options.inSampleSize--; bitmap = BitmapFactory.decodeFile( filename, options ); if ( bitmap != null && exact ) { bitmap = Bitmap.createScaledBitmap( bitmap, width, height, false ); } } return bitmap; } 

顺便说一句,在较新的API也有很多BitmapFactory.Option的适合图像来DPI屏幕,但我不知道他们是否真的简化了任何东西。 使用android.util.DisplayMetrics.density或者只是一个固定的大小来减less内存消耗似乎更好地工作。

参照这个链接 ,请注意outOfMemory错误可以通过以下方式解决:

 public Bitmap decodeFile(String filePath) { Bitmap bitmap = null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inPurgeable = true; try { BitmapFactory.Options.class.getField("inNativeAlloc").setBoolean(options,true); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } if(filePath != null) { bitmap = BitmapFactory.decodeFile(filePath, options); } return bitmap; } 

一定要防止你的位图创build内存不足的错误! 对于大多数平台来说,android并没有太多的内存可以使用,并且通过位图快速运行。 另外,请确保尽可能手动回收您的位图,我注意到垃圾收集可能相当慢。

 try{ Bitmap myFragileBitmap = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888); } catch(IllegalArgumentException e){ Log.e(TAG,"Illegal argument exception."); } catch(OutOfMemoryError e){ Log.e(TAG,"Out of memory error :("); } 

我结束了调整位图使用下面的代码似乎已经解决了这个问题。

 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 8; Bitmap preview_bitmap = BitmapFactory.decodeFile(mPathName, options); 

我认为这是 – 它说的是什么。 您的图片太大,因为当内存耗尽时,它被加载到stream中,引发exception。 这甚至不是关于你有多less内存,而是你的特定活动有多less的问题。

在decodefile中使用这些选项。 希望你可以select位图超过预算的问题..

 BitmapFactory.Options bfOptions=new BitmapFactory.Options(); bfOptions.inDither=false; //Disable Dithering mode bfOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared bfOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future bfOptions.inTempStorage=new byte[32 * 1024]; 

你检查过DDMS吗? 与我遇到的,可能不是图像的大小,因为Android似乎很好地处理大型图像。 如果你用DDMS跟踪堆,你可能会发现你碰巧拥有大量的空闲内存。 你可以通过添加这个来“扩展”你的堆

 static { @SuppressWarnings("unused") byte dummy[] = new byte[ 8*1024*1024 ]; } 

到你的代码,强制堆扩展。 这可能会减less一点。 不幸的是,它声称它不能分配一定数量的字节。 说1M。 如果你看一下“免费”的行,你会发现最大的块是>> 1M。 那里有一些奇怪的东西,我无法弄清楚。 它甚至与滑动图像的速度无关。 我在一些线程中看到,您可以称之为“回收”或者位图。 我仍然不明白为什么它应该帮助,如果堆大小远高于所采取的大小。

我得到这个错误,当我开始从320×240的图像resize像64×240(缩放),然后导入到我的项目(因为我想提高渲染速度,它包含了很多无用的alpha区域,直到这一点)。

现在最后的答案是有道理的:

你可以通过添加这个静态{@SuppressWarnings(“unused”)dummy dummy [] = new byte [8 * 1024 * 1024]来“扩展”你的堆。 }到你的代码,强制堆扩展。 这可能会减less一点。

我想这是发生在我身上的事情。 Android会自动将drawables解码成位图,(然后在编译的时候存储在堆上)

我开始看到这个错误,当我在运行时使用较小版本的图像时(我使用BitmapFactory.decodeResource和Bitmap.createScaledBitmap编写了一个带有复古graphics的VGA游戏。

它必须像Marve所说的那样:在缩小我的drawable / image并将其导入到我的项目之后,堆在我的情况下不够大。

我能够摆脱我的OutOfMemoryException重新调整图像回到一个更大的尺寸(320×240),这validation了我猜的问题?