从外部存储加载位图时引发了OutOfMemory异常。

17

在我的应用程序中,我从JPEG和PNG文件中加载了一些图像。当我将所有这些文件放入资产目录并以这种方式加载时,一切都正常:

InputStream stream = getAssets().open(path);
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, null);
stream.close();
return new BitmapDrawable(bitmap);

但是当我尝试从SD卡加载完全相同的图像时,会出现OutOfMemory异常!

InputStream stream = new FileInputStream("/mnt/sdcard/mydata/" + path);
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, null);
stream.close();
return new BitmapDrawable(bitmap);

这是日志中的内容:

11-05 00:53:31.003: ERROR/dalvikvm-heap(13183): 827200-byte external allocation too large for this process.
11-05 00:53:31.003: ERROR/GraphicsJNI(13183): VM won't let us allocate 827200 bytes
...
11-05 00:53:31.053: ERROR/AndroidRuntime(13183): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
11-05 00:53:31.053: ERROR/AndroidRuntime(13183):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
...

为什么会发生这种情况?

更新:在真实设备上尝试了这两个方法 - 看来我无法将超过12MB的位图加载到所谓的“外部存储器”中(这不是SD卡)。


你在什么条件下测试上述代码?是在模拟器中还是连接 USB 的真实设备上?有可能你的 USB 模式被设置为磁盘模式,这会锁定 SD 卡。 - xandy
我在模拟器中运行这段代码。 - Fixpoint
我加载的最大JPG文件大小为400KB,它是800x600x24。 - Fixpoint
也许你应该将图像分成4、8或16个瓦片。很可能你有足够的空闲内存,但不足以进行一次大规模的连续分配。 - Reuben Scratton
Reuben,我尝试使用一个小图像(以位图形式为50KB)重复加载到内存中,总共12MB,如果我从SD卡加载它,我总是会遇到异常。 - Fixpoint
显示剩余2条评论
12个回答

0

用另一种方式尝试这个...

Bitmap bmpOrignal = BitmapFactory.decodeFile("/sdcard/mydata/" + path");

尝试使用InputStream后结果相同:OutOfMemory。 - Fixpoint

0

你不能依赖GC来回收你的位图内存。 当不再需要时,必须清楚地回收位图。

请参阅Bitmap方法:

void recycle() 释放与此位图的像素关联的内存,并将位图标记为“无效”,这意味着如果调用getPixels()或setPixels(),它将抛出异常,并且不会绘制任何内容。


我不想回收所有这些位图,因为我正在使用它们。 - Fixpoint
如果一个位图被隐藏了,最好回收它们。如果它们再次显示,你需要重新加载它们。手机的内存是有限的。 - imcaptor
当尝试加载已被回收的位图时,会抛出一个异常,提示无法加载已回收的位图。 - AjOnFire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接