0

我的家庭布局中有 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

4 回答 4

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" 

谢谢!

于 2013-06-05T11:20:45.990 回答
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;
        }
于 2013-06-05T11:11:17.377 回答
1

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

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

于 2013-06-05T10:58:04.940 回答
1

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

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

计算样本大小并减小位图大小的方法

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;
}
于 2013-06-05T11:28:46.320 回答