如何克服这个问题引起:java.lang.OutOfMemoryError:位图大小超过VM预算

时间:2011-06-09 14:43:35

标签: android

我正在从XML解析图像并在My Android Application中显示它。我的问题是当解析超过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)

7 个答案:

答案 0 :(得分:5)

当我为我制作的文件编辑器缩略图像时,我遇到了同样的问题。你想要做的是在将图像存储到内存之前缩小图像,并在读取后从系统内存中处理源图像

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

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);

}

答案 1 :(得分:2)

通常,只有一种解决方案:使用较小的图像。如果没有代码,很难说出什么是错误的。您可以尝试降低图像尺寸。

答案 2 :(得分:1)

当您通过BitmapFactory读取位图时,将BitmapFactory.Option inScaled参数设置为2或4(或适合您的任何内容),以创建更小,内存更少的图像

答案 3 :(得分:0)

我遇到了同样的问题。尝试重用位图和画布。

答案 4 :(得分:0)

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

每当您将大量图像加载到内存中时,此空间会非常快速地填满,从而导致抛出OutOfMemoryError。为了解决这个问题,您应该(如先前的答案所述)将图像缩小为缩略图并仅将缩略图保留在设备存储器中(减少内存占用)并将图像保存到SDCARD。

您可以从Eclipse中的DDMS布局查看程序使用了多少内存。我相信你也可以覆盖Application类来监听“低内存”警告功能。

答案 5 :(得分:0)

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

2)使用压缩图像。

答案 6 :(得分:0)

如果您的应用程序有时工作正常,并且突然间您会因内存不足而崩溃,那么您可能会在创建位图时浏览活动。

您可能想尝试this