我将100张图片从Asset文件夹加载到一个数组对象中。图片非常小(每个图片都是png ~20k ),为了防止内存泄漏和优化性能,我使用下面的代码对其进行了修改:
在循环中:
// create resized bitmap from asset resource
InputStream istr = assetManager.open(pics[i]);
Bitmap b = BitmapFactory.decodeStream(istr);
b = Bitmap.createScaledBitmap(b, 240, 240, true);其中picsi是位于my Asset文件夹中的文件名列表。
代码对我有效,但我仍然会时不时地收到来自用户的错误(我在开发人员控制台错误中看到它):
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:468)
at android.graphics.Bitmap.createBitmap(Bitmap.java:435)
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340)我能做些什么来改进它吗?或者这是Android的世界,我们永远不能交付一个完美的应用程序?
发布于 2011-08-18 21:41:49
当然,你可以改进一些东西:不要同时在内存中加载太多的图片(或者减小它们的大小)。有些设备没有太多可用内存。您的设备可能比您的某些客户电话具有更高的堆限制。因此,当它为您工作时,它会崩溃(有关4:44的一些堆限制,请参阅this video )。
您可以通过ActivityManager.getMemoryClass()获取可用的堆大小。
要改善这一点,请测试哪些图片是您现在需要的(哪些显示了),哪些不是。只加载需要的位图,并回收不再需要的位图。
也可以尝试使用BitmapFactory.decodeResource()和BitmapFactory.Options.inSampleSize。这允许您以较低的分辨率直接加载图像,而不是以全尺寸加载图像,然后像您在这里所做的那样调整大小。
发布于 2011-08-18 21:38:52
位图不是压缩的,所以它们以width * height * 4字节存储。这意味着每个图像使用大约225KB的内存。100张图像需要大约22MB的内存。最小堆大小为16 MB,但设备通常具有24+ MB堆。这个堆不仅用于数据,还用于活动、视图等。这意味着你不能加载100个这种大小的位图。
发布于 2011-08-18 22:11:35
根据经验,您应该只需要来显示用户实际可以看到的内容。在内存中保存任何其他内容(图形)只是锦上添花。这就是为什么屏幕分辨率更高的设备会有更大的堆大小可用。
例如,在320x480的屏幕上,您至少需要320x480x4=614400 (600kb)。
考虑到这个概念,您需要考虑是否需要在内存中容纳100个Bitmap。用户是否一次查看100个Bitmap?在这种情况下,您可以在不降低用户体验的情况下降低图像质量(屏幕上只有这么多像素)。用户是否正在滚动100个Bitmap?然后根据需要动态地转储和加载图像(使用一些缓存以保证流畅性)。
总是有一种变通方法。
https://stackoverflow.com/questions/7108169
复制相似问题