Android 使用照相机的应用程序出错:java.lang.OutOfMemoryError:位图大小超出VM预算

Android 使用照相机的应用程序出错:java.lang.OutOfMemoryError:位图大小超出VM预算,android,database,bitmap,virtual-machine,Android,Database,Bitmap,Virtual Machine,很抱歉,我可能会发布一个类似于许多其他问题的问题,但我找不到解决方案,也找不到类似于此错误发生的情况。我在谷歌上搜索了一周又一周,试图找到这个问题的答案,但到目前为止运气还不好。我对android相当陌生,所以如果这是显而易见的,这可能就是原因 以下是导致错误的步骤: 应用程序使用相机拍照 该图像随后存储在SD卡上的文件夹中 制作此文件的副本,并将其压缩到每个图像50-100kb(这就是我试图显示的内容) 然后,我将图像的初始大小和文件名存储在sqlite数据库中 当活动(onResume我这样

很抱歉,我可能会发布一个类似于许多其他问题的问题,但我找不到解决方案,也找不到类似于此错误发生的情况。我在谷歌上搜索了一周又一周,试图找到这个问题的答案,但到目前为止运气还不好。我对android相当陌生,所以如果这是显而易见的,这可能就是原因

以下是导致错误的步骤:

应用程序使用相机拍照
该图像随后存储在SD卡上的文件夹中
制作此文件的副本,并将其压缩到每个图像50-100kb(这就是我试图显示的内容)
然后,我将图像的初始大小和文件名存储在sqlite数据库中
当活动(onResume我这样做)加载时 如果数据库中有任何文件名,它将获取文件名并显示图像-这就是错误所在

if(c.getCount() > 0) {

   String[] cols = new String[] {DBAdapter.FILENAME,DBAdapter.DATETIME};

    int[] values = new int[] {R.id.thumbnail,R.id.datetime_stamp};

    SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, R.layout.image_listview, c, cols, values, 0);

    ListView listView = (ListView) findViewById(android.R.id.list);
    listView.setAdapter(cursorAdapter);
    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> listView, View view, int position, long id) {
            String row = c.getString(c.getColumnIndexOrThrow(DBAdapter.KEY_ID)); // row ID from transactions
            Toast.makeText(getBaseContext(), row, Toast.LENGTH_SHORT).show();
        }
    });
}

提前感谢您的帮助。

首先:不要将图片保存在数据库中。将其保存到sd并在DB(文件路径)中放置一个引用。数据库不是为大的二进制数据而设计的(可能会大大降低它们的速度)

其次,我认为您提供的报价片段中不存在错误。如果你从相机上拍摄一张照片,我假设它至少是5MP,你必须注意不要将整个照片作为位图加载,因为它需要至少114 MB的Ram才能在24位上拍摄一张5MP的照片,但你只有大约24位。您要做的是将缩小的版本加载到UI中。首先使用以下方法获取尺寸:

// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
然后检查需要缩小多少(应为2的幂),并使用正确的采样选项对其进行解码

 // Calculate inSampleSize
options.inSampleSize = 8;

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

请在

上阅读更多信息,我怀疑这实际上就像这里的许多类似问题一样。您正在尝试加载一个非常大的位图。不管它在磁盘上是否压缩到50-100KB,在内存中占用的空间会更多。@TheT4llOne-你看过答案了吗?@kabuko-我看不出还有什么可能,因为这是活动的所有加载位,删除它,活动不会崩溃。这里是整个活动代码的副本,如果有帮助的话:@Derek-是的,我看到了这个问题,但没有太大帮助,但谢谢你的建议:)对不起,如果我不清楚,我目前已经在数据库中找到了路径,当我加载活动时,出现了多个图像,它崩溃了。如何从路径加载缩放图像并将其插入listview?感谢检查我提供的链接,这是一个如何逐步缩小和加载位图的步骤:我认为其余的都是straigt for3st。嗨@for3st,感谢到目前为止的帮助,很抱歉听起来像是一个坏记录,但我仍然无法弄清楚这一点,因为我只有路径,它将直接指向listView,下面是完整的代码,您可以看到:
 // Calculate inSampleSize
options.inSampleSize = 8;

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