使用2位图时出现OutOfMemoryError

时间:2013-06-05 10:45:37

标签: android android-layout bitmap out-of-memory

我的家庭布局上有2 ImageView,其内容来自SD卡上的图片,如下面的代码段所示:

try {
        String tempPath1 = Environment.getExternalStorageDirectory()
                + File.separator + "Clipping_Pictures" + File.separator
                + "06-05-2013_02-06-09pm.png";
        File f = new File(tempPath1);
        Bitmap b = null, b2 = null;
        b = BitmapFactory.decodeFile(f.getPath());

        if (f.exists()) {
            ivClip1.setImageBitmap(b);//ivClip1 is ImageView
        }

        tempPath1 = Environment.getExternalStorageDirectory()
                + File.separator + "Clipping_Pictures" + File.separator
                + "06-05-2013_02-06-33pm.png";
        f = new File(tempPath1);
        b2 = BitmapFactory.decodeFile(f.getPath());

        if (f.exists()) {
            ivClip2.setImageBitmap(b2);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

当我第一次加载应用程序时,它会在各个图像视图上显示两个图像。但第二次发布,应用程序崩溃,以下例外:
OutOfMemoryError:位图大小超过VM预算

请注意两个资源图片是 .png ,大小约为850kb,我认为应该没问题。

在SO和互联网上有类似的主题,我尝试了一些他们建议的解决方案,但似乎都没有。

任何帮助表示感谢。

4 个答案:

答案 0 :(得分:3)

如果您在病房中为Android 3.0构建应用程序,则可以在清单文件的应用程序标记中使用android:largeHeap="true"属性。 这样做,希望您的应用程序不会因内存不足而崩溃。

以下是示例:

应用

android:allowBackup="true"
android:icon="@drawable/icon_96x96"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@android:style/Theme.NoTitleBar" 

谢谢!

答案 1 :(得分:1)

您是从onCreate()还是从onResume()执行所有这些代码?

在尝试再次加载图像(ivClip1.setImageBitmap(null)或轻量级图像)之前,您可能会尝试清理视图,因为在解码两个位图时,您在显示时仍然在内存中存在先前的实例。

答案 2 :(得分:1)

因为你的位图很大。使用以下代码压缩您的位图:

Bitmap ShrinkBitmap(byte[] file, int width, int height){

         BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
            bmpFactoryOptions.inJustDecodeBounds = true;
            Bitmap bitmap = BitmapFactory.decodeByteArray(file, 0, file.length, bmpFactoryOptions);


            int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
            int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);

            if (heightRatio > 1 || widthRatio > 1)
            {
             if (heightRatio > widthRatio)
             {
              bmpFactoryOptions.inSampleSize = heightRatio;
             } else {
              bmpFactoryOptions.inSampleSize = widthRatio;
             }
            }

            bmpFactoryOptions.inJustDecodeBounds = false;
            bitmap = BitmapFactory.decodeByteArray(file, 0, file.length, bmpFactoryOptions);
         return bitmap;
        }

答案 3 :(得分:1)

您可以添加此行来调整位图大小,然后使用它

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file),null,options);

计算sampleize和减小位图大小的方法

private Bitmap decodeFile(File f){
    try {
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        final int REQUIRED_SIZE=70;

        //Find the correct scale value. It should be the power of 2.
        int scale=1;
        while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
            scale*=2;

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}