加载drawable时的堆大小为90MB

时间:2014-03-22 19:26:57

标签: android image memory

我想显示来自用户设备的一些图像的预览。为此,我在外部存储器中搜索图像文件,对于包含某些文件夹的每个文件夹,我在列表视图中列出文件夹的名称和该文件夹中的图像。 在我的Nexus上有6个包含图像的文件夹,所以我有6个listview项目。 我使用以下方式加载所有图像:

Drawable.createFromPath(file.getAbsolutePath())

将生成的drawable缓存在HashMap中,以防止多次加载相同的图像。

然而,堆从20MB增长到> 90MB。加载图像后,应用响应延迟2秒。非常糟糕。

我不知道堆如何从6张像50KB的图像增长到90MB但是无论如何。为了解决这个问题,我尝试从图像中加载子采样位图 - 但是每当我加载它们时,我都会得到一个outofmemory异常。

我已多次验证不超过这6张图片的加载次数。 我该怎么办?

2 个答案:

答案 0 :(得分:1)

你应该做的是使用MAT工具分析应用程序的内存使用情况,如this惊人文章中所述。此工具将帮助您识别潜在的内存泄漏,并查看究竟是什么触发了堆增长。

答案 1 :(得分:0)

我使用了Egor描述的工具并且没有内存泄漏。图像大约需要30MB堆。只能通过缩小图像尺寸来减少此数量。我的解决方案使用子采样,现在大约需要3MB堆。

private Drawable loadDrawable(Context context, File file) {
        Drawable drawable = drawables.get(file);
        if (drawable == null) {
            final int targetSize = 500;

            // get subsampling factor
            Options opts = new Options();
            opts.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(file.getAbsolutePath(), opts);
            int largest = opts.outWidth > opts.outHeight ? opts.outWidth : opts.outHeight;
            float factor = largest / (float) targetSize;
            factor = Math.round(factor);

            // load bitmap with subsampling
            opts = new Options();
            opts.inSampleSize = (int) factor;
            Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), opts);
            drawable = new BitmapDrawable(getResources(), bitmap);
            drawables.put(file, drawable);
        }
        return drawable;
    }