如何避免内存不足错误?

时间:2014-07-18 17:40:05

标签: android bitmap bitmapfactory

我正在开发游戏,我使用Bitmap files加载52 BitmapFactory,并在运行应用时。我收到了OutOfMemoryError。那是因为drawable文件夹中的图片是.JPG而不是.PNG吗?请让我知道如何解决这个问题。

2 个答案:

答案 0 :(得分:1)

JPG与PNG无关,因为当您加载位图时,将它们解压缩为原始数据(基本上与bmp相同)。未压缩,每个位图使用4 *宽*高度字节。根据图像的大小,可能会非常大。我建议使用一个固定大小的LRUCache,只保存你在内存中实际需要的图像并踢出未使用的图像。

答案 1 :(得分:0)

我正在处理我的应用程序中的196张png图片,当我尝试加载所有图片时也遇到了内存不足。我的图像是png,这意味着将它们从jpg转换为png没有帮助。

我不知道它是否是最佳解决方案,但我所做的是从我的主要活动的OnCreate()方法开始一个IntentService,第一次调用它。在内部,我检查内部存储器上是否已存储较小版本的图像。如果已经创建了较小的版本,我会维护它们的列表,并在我需要显示它们时在我的活动中使用它们。如果它们不存在(当用户第一次安装应用程序时发生,或者从此应用程序的设置中清除缓存),我通过调用具有所需宽度和高度的decodeSampledBitmapFromResource()来创建它们。所需的宽度和高度可以存储在xml文件中,并且特定于不同的屏幕。下面提供了我在维护图像方面时用于调整大小的功能。

/**
 * Calculate in sample size.
 *
 * @param options the options
 * @param reqWidth the req width
 * @param reqHeight the req height
 * @return the int
 */
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;
}

/**
 * Decode sampled bitmap from resource.
 *
 * @param res the res
 * @param resId the res id
 * @param reqWidth the req width
 * @param reqHeight the req height
 * @return the bitmap
 */
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}