Android BitmapFactory.decodeFile减速直到内存不足

时间:2014-06-22 20:10:50

标签: android bitmapfactory

我正在处理多达1200张图片。借助之前的问题,我优化了它,从100张图片到500张图片。现在,这就是我所拥有的:

   public Bitmap getBitmap(String filepath) {
        boolean done = false;
        int downsampleBy = 2;
        Bitmap bitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filepath, options);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        options.inPreferredConfig = Config.RGB_565;
        while (!done) {
            options.inSampleSize = downsampleBy++;
            try {
                bitmap = BitmapFactory.decodeFile(filepath, options);
                done = true;
            } catch (OutOfMemoryError e) {
                // Ignore.  Try again.
            }
        }
        return bitmap;
    }

这个函数在一个循环中被调用,它会非常快,直到它到达第500个图像。此时它会减速,直到它最终停止在第600张图像周围工作。

此时我不知道如何优化它以使其工作。您认为发生了什么?我该如何解决?

修改

            // Decode BItmap considering memory limitations
    public Bitmap getBitmap(String filepath) {
        Bitmap bitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filepath, options);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        options.inPreferredConfig = Config.RGB_565;
        options.inDither = true;
        options.inSampleSize= calculateInSampleSize(options, 160, 120);

        return bitmap = BitmapFactory.decodeFile(filepath, options);
    }

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

对已接受的答案进行了更改。使用Google教程中的函数来获取正确的样本大小。在清单中添加了largeHeap,并且在遍历所有图像之前只调用了System.gc()一次。

1 个答案:

答案 0 :(得分:2)

首先,你永远不应该期望得到一个错误。这里描述:Java documentation 错误是Throwable的一个子类,表示合理的应用程序不应该试图捕获的严重问题。

有关加载位图的一些帮助:Android Developers | Loading large bitmaps

通过在Application Manifest中声明largeHeap="true"属性,您可以获得更多内存。

此外,System.gc()调用可能有助于释放一些未使用的内存,但我不会真正依赖该调用。