Android 如何克服以下问题:java.lang.OutOfMemoryError:位图大小超出VM预算

Android 如何克服以下问题:java.lang.OutOfMemoryError:位图大小超出VM预算,android,Android,我正在解析XML中的图像,并将其显示在我的Android应用程序中。我的问题是,当解析超过20个图像时,会出现以下错误 06-09 14:28:37.710: ERROR/AndroidRuntime(490): java.lang.RuntimeException: An error occured while executing doInBackground() 06-09 14:28:37.710: ERROR/AndroidRuntime(490): at android.os.

我正在解析XML中的图像,并将其显示在我的Android应用程序中。我的问题是,当解析超过20个图像时,会出现以下错误

06-09 14:28:37.710: ERROR/AndroidRuntime(490): java.lang.RuntimeException: An error occured while executing doInBackground()
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at java.lang.Thread.run(Thread.java:1096)
06-09 14:28:37.710: ERROR/AndroidRuntime(490): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
06-09 14:28:37.710: ERROR/AndroidRuntime(490):     at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657)

通常,只有一种解决方案:使用较小的图像。如果没有代码,很难说到底出了什么问题。您可以尝试降低图像大小。

当您通过
位图工厂
读取位图时,将参数设置为2或4(或任何适合您的参数),以创建更小、内存占用更少的图像。

我曾经在为我制作的文件编辑器绘制图像时遇到过同样的问题。您要做的是在将图像存储到内存之前收缩图像,并在读取源图像后从系统内存中处理它们

这是我为我使用的代码,它将图像缩小到110x110,但您可以设置自己的算法来缩放它(我相信resizedbitmap类中实际上已经有一个函数用于此,但我没有使用它)


我也有同样的问题。尝试重用位图和画布。

许多设备的可用内存非常有限。许多旧设备为应用程序分配16MB内存,而一些更现代的设备可能分配24MB甚至32MB(我见过只有14MB的设备)

每当您将如此多的图像加载到内存中时,这个空间就会很快填满,从而引发OutOfMemoryError。要解决这个问题,您应该(正如前面的答案所说)将图像缩小为缩略图,只将缩略图保留在设备内存中(减少内存占用),并将图像保存到SD卡

您可以从Eclipse中的DDMS布局中看到程序使用了多少内存。我相信您还可以重写应用程序类来侦听“内存不足”警告函数

1)要解决此问题,请在清单文件中添加android:installLocation=“preferExternal”


2) 使用压缩图像。

如果你的应用程序有时工作正常,但突然在内存不足的情况下崩溃,那么你可能正在浏览活动,同时在其中创建位图


正如@Egor所说,您可能想尝试一下,您需要发布一些代码,这样我们就可以看到发生了什么。当你说“解析20多个图像”时,你是在单独“解析”它们吗?如果是这样的话,你做了多少并不重要,因为这样做时你不需要在内存中保留前19个。谢谢亲爱的,这篇文章对我很有帮助。我问另一件事,当我们得到sdcard的目录结构时,如何从sdcard中筛选一些文件夹。我不明白你在问什么。请澄清我已经得到了这个答案,我不想显示目录结构中的系统文件夹,所以我做得很好。谢谢你的回复
public void setImageFromFile(String filename) {
    ImageView fileImage = (ImageView)findViewById(R.id.file_image_holder);
    Bitmap icon = BitmapFactory.decodeFile(filename);
    int width = icon.getWidth();
    int height = icon.getHeight();
    int newWidth = 110;
    int newHeight = 110;
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;

    Matrix bMatrix = new Matrix();
    bMatrix.postScale(scaleWidth, scaleHeight);

    Bitmap resizedBitmap = Bitmap.createBitmap(icon, 0, 0, width, height, bMatrix, true);
    BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
    fileImage.setImageDrawable(bmd);

}