1

我知道这个问题已经在这个论坛上被问过很多次了,但我仍然无法得到完美的答案来解决这个问题。

在我的应用程序中,我使用 3 种不同尺寸的相同图像:小、中、大。

当我多次使用这些图像时,我得到了这个错误。

08-24 11:08:55.994: E/ImageLoader(636): bitmap size exceeds VM budget
08-24 11:08:55.994: E/ImageLoader(636): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
08-24 11:08:55.994: E/ImageLoader(636):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
08-24 11:08:55.994: E/ImageLoader(636):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459)
08-24 11:08:55.994: E/ImageLoader(636):     at com.nostra13.universalimageloader.core.ImageDecoder.decode(ImageDecoder.java:75)
08-24 11:08:55.994: E/ImageLoader(636):     at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeWithOOMHandling(LoadAndDisplayImageTask.java:161)
08-24 11:08:55.994: E/ImageLoader(636):     at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:148)
08-24 11:08:55.994: E/ImageLoader(636):     at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:104)
08-24 11:08:55.994: E/ImageLoader(636):     at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:58)
08-24 11:08:55.994: E/ImageLoader(636):     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
08-24 11:08:55.994: E/ImageLoader(636):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-24 11:08:55.994: E/ImageLoader(636):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-24 11:08:55.994: E/ImageLoader(636):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
08-24 11:08:55.994: E/ImageLoader(636):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
08-24 11:08:55.994: E/ImageLoader(636):     at java.lang.Thread.run(Thread.java:1096)

任何人都可以帮助解决它..我已经搜索了很多相同的问题,但我仍然没有得到这样的解决方案..

这就是为什么我必须在凌晨四点写下这个问题。

我正在等待积极的答复..

谢谢。

4

5 回答 5

1

这是图像的常见问题。Android 为每个应用程序提供了一定数量的空间。在没有缩小尺寸的情况下拍摄的图像往往会导致这个问题。最好的解决办法是

BitmapFactory.Options options = new BitmapFactory.Options();

options.inSampleSize = 8;(此处使用值作为 2 的幂以获得最佳解决方案)

并在您解码时将它们传递给位图

Bitmap bm = BitmapFactory.decodeStream(<input image file>, null, options);

于 2012-08-24T06:14:29.377 回答
0
Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget

这意味着设备内存不足并被强制关闭。

现在,既然您说多次使用图像时会出现错误,我相信您并没有释放资源。位图有时会占用大量空间,如果您将它们保存在内存中,如果设备出现 OOM,我不会感到惊讶。不同的设备有不同的内存规格,经过几次运行,它就会填满内存。

因此,我的建议是清除位图和您用于临时目的的其他存储。

如果这仍然不能解决您的问题,请将代码发布到您处理图像的位置,我们将尝试查看是否有更高效的内存方式来处理您正在做的事情。

祝你好运!

于 2012-08-30T12:18:33.200 回答
0

我认为您可以使用失败重试机制来解决此问题。

喜欢:尝试正常加载图像,如果失败,从 catch 块,尝试使用 BitmapConfig (Bitmap.Config.ARGB_4444) 以降低的质量加载它,如果再次失败,尝试以更低的质量加载它 (Bitmap.配置.ALPHA_8)。我也有同样的问题,现在这个方法对我有用。

Bitmap imageBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = false; 
options.inPurgeable = true;
options.inInputShareable = true; 
options.inTempStorage = new byte[32 * 1024];
options.inPreferredConfig = config;//Bitmap.Config.ARGB_4444 or Bitmap.Config.ALPHA_8 when failed  
options.inSampleSize = 1;
imageBitmap = BitmapFactory.decodeFile(bitmapPath, options);
于 2012-08-24T06:21:04.673 回答
0

这是一个老问题,但我最终浪费了一整天时间尝试使用出色的 UIL 修复旧设备上的图像内存问题。这些答案都不是 UIL 特有的,我的解决方案最终来自于偶然发现 Nostra 自己回答的这个问题:

如何在使用 Android 通用图像加载器在视图中显示图片之前调整其大小?

对我来说,这里的maxImageWidthForMemoryCache和高度值非常重要。我正在下载并显示大约屏幕大小的图像,并将其放置在屏幕宽度和高度的图像视图中,因此实际上没有发生任何缩放。这对于我的 2.3 手机来说太大了,将尺寸减半对图像质量几乎没有明显的影响有很大帮助。

于 2014-05-02T00:52:06.223 回答
0

您可以使用此方法来解码位图:

public static Bitmap loadBitmap() {
    FileInputStream fis = null;
    Bitmap bitmap = null;

    BitmapFactory.Options option = new BitmapFactory.Options();
    option.inDither = false;
    option.inPurgeable = true;
    option.inInputShareable = true;
    option.inTempStorage = new byte[32 * 1024];
    option.inPreferredConfig = Bitmap.Config.RGB_565;

    try {
        fis = IOHelper.openInputStream(); //get the picture's FileInputStream
        FileDescriptor fd = fis.getFD();
        bitmap = BitmapFactory.decodeFileDescriptor(fd, null, option);
    } catch (IOException e) {

    } finally {
        IOHelper.closeQuietly(fis);
    }
    return bitmap;
}
于 2012-08-24T06:35:25.410 回答