Android BitmapFactory.decode文件的速度会减慢,直到内存不足

Android BitmapFactory.decode文件的速度会减慢,直到内存不足,android,bitmapfactory,Android,Bitmapfactory,我正在处理多达1200张图像。在前面的问题的帮助下,我优化了它,从100张图片到500张。现在,这就是我所拥有的: public Bitmap getBitmap(String filepath) { boolean done = false; int downsampleBy = 2; Bitmap bitmap = null; BitmapFactory.Options options = new BitmapFactor

我正在处理多达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幅图像附近停止工作

在这一点上,我不知道如何优化它,使其工作。你认为发生了什么事?我该如何解决

编辑


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

首先,您不应该期望捕获错误。此处描述:错误是Throwable的一个子类,表示合理的应用程序不应试图捕获的严重问题。

有一些关于加载位图的帮助:

通过在应用程序清单中声明
largeHeap=“true”
属性,可以获得更多内存


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

我不知道这是否是一个糟糕的计划,但您是否尝试调用System.gc()来防止内存耗尽?@Zhuinden我没有,我应该在哪里调用它?我在StackOverflow答案中找到它后这样做了。在我看来,这并不是正确的方法,但从这个问题来看,它比caculateInSampleSize函数工作得更好:我将尝试更改largeHeap属性和System.gc()调用,并通过添加largeHeap并调用System.gc()来查看它是否有助于@sipkab。我让它处理1200个图像中的788个。所以它确实有帮助,但是它在788崩溃了。您可以在每次尝试加载图像之前尝试调用
System.gc()
。垃圾收集器将尝试释放尽可能多的内存,包括以前回收的位图。谢谢,这就是我现在正在做的。在我的Nexus 5上进行了测试,所有图像都已处理,但该应用程序将使用的设备尚未运行。我不知道这是否只是一个硬件限制,还有其他方法可以释放更多内存吗?谢谢你的帮助。由于设备不是很强大,我决定降低图像的质量,效果很好。我担心这不是最终的解决方案,因为我相信如果有更多的图像,它将不起作用。我接受你的回答,因为这正是我现在需要的!再次感谢
            // 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;
}