0

在最后一行我遇到了崩溃:

InputStream in = new BufferedInputStream(new FileInputStream(file));
byte[] buf = new byte[(int) file.length()];
int numRead = in.read(buf);
final Bitmap bitmap = BitmapFactory.decodeByteArray(buf, 0, numRead); <--- crash

如何避免?

E/dalvikvm-heap: Out of memory on a 31961104-byte allocation.

我明白 31MB 是使用内存的限制吗?用于LRUCache存储图像。我设置了 60MB 来存储数据。是不是太多了?

public static int cacheSize = 60 * 1024 * 1024; // 4MiB
    public static LruCache<String, Bitmap> images = new LruCache<String, Bitmap>(cacheSize) {
        protected int sizeOf(String key, Bitmap value) {
            return value.getByteCount();
        }
    };

在我的例子中,一个图像大约是 3MB,我需要至少 18 个图像存储在缓存中。手机存储60MB的需求这么大吗?

我尝试了代码,为什么应用程序终止?

4

1 回答 1

2

如何避免?

好吧,您可以通过使用decodeStream()而不是来帮助您的事业decodeByteArray()。就目前而言,通过在解码之前读取整个编码图像,您会毫无意义地浪费堆空间。

但是,一般而言,您的问题与 . 无关LRUCache,而与尝试进行大 (~30MB) 分配有关。31961104 字节,作为Bitmap,相当于 2826 x 2826 像素的图像。这比大多数 Android 屏幕大得多。您可能没有一个连续的堆空间块供其中一个使用,更不用说 18 了。对于低端 Android 设备,18 可能占用比整个设备更多的内存。

我明白 31MB 是使用内存的限制吗?

否。该错误表明您没有足够的可用内存块用于该映像。

在我的情况下,图像大约是 3MB

也许在磁盘上。大多数图像文件格式都是压缩的(PNG、JPEG、WebP、GIF 等)。您使用的堆空间量取决于解压缩后的大小。正如 njzk3 所指出的,堆空间基于分辨率(宽度 x 高度,以像素为单位)和位深度(默认情况下每像素 4 个字节)。

我能做些什么?

使用较小的位图。

或者,不要将整个位图加载到内存中,而是使用可以根据用户平移和缩放手势按需逐步加载图像的小部件。

于 2017-02-14T16:44:30.900 回答