Android中位图factory.decodefile的java.lang.outofmemory错误

时间:2013-04-25 02:53:52

标签: android bitmap

首先我调用MediaStore.ACTION_IMAGE_CAPTURE意图打开相机然后我从此功能获取保存的捕获图像路径。

private String getLastImageId(){
    String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA };
    String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
    Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
    if(imageCursor.moveToFirst()){
        int id = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));
        String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
        //imageCursor.close();
        return fullPath;
    }else{
        return "";
    }
}

然后我将该路径作为参数传递给产品对象属性。 将该对象添加到产品列表中 该列表由自定义适配器显示。 我在listView

中显示产品标题和图像

在自定义适配器类中,我从中获取产品获取产品标题和路径 从路径创建一个位图并将其指向包含图像视图的产品持有者 以这种方式为第一张照片工作很好,但在第二张照片上它给出了java.lang.outofmemory的例外,我也试过了

给出的解决方案

java.lang.OutOfMemoryError: bitmap size exceeds VM budget - Android

在产品适配器中执行此操作

public class ProductAdopter extends ArrayAdapter<Product> {
Context context; 
int layoutResourceId;    
ArrayList<Product> data = null;
public ProductAdopter(Context context, int layoutResourceId, ArrayList<Product> product_data) {
    // TODO Auto-generated constructor stub
    super(context, layoutResourceId, product_data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = product_data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    ProductHolder holder = null;

    if(row == null)
    {
        LayoutInflater inflater = ((MainActivity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new ProductHolder();
        holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
        holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);

        row.setTag(holder);
    }
    else
    {
        holder = (ProductHolder)row.getTag();
    }

    Product product = data.get(position);
    holder.txtTitle.setText(product.getName());
    File imgFile = new  File(product.icon);
    if(imgFile.exists()){

        Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());

        holder.imgIcon.setImageBitmap(myBitmap); 
        //myBitmap.recycle();
    }
    return row;
}
static class ProductHolder
{
    ImageView imgIcon;
    TextView txtTitle;
}
}

3 个答案:

答案 0 :(得分:4)

 if(imgFile.exists()){

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 8;

   Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(),options);
        holder.imgIcon.setImageBitmap(myBitmap); 
        //myBitmap.recycle();
    }

使用inSampleSize将位图加载到内存。对inSampleSize值使用2的幂对于解码器来说更快且更有效。但是,如果您计划将已调整大小的版本缓存在内存或磁盘上,通常仍需要解码到最合适的图像尺寸以节省空间。

有关详情,请参阅Loading Large Bitmaps Efficiently

答案 1 :(得分:0)

如果您尝试自己解码大图像,则会遇到内存不足问题。

尝试使用Universal Image loader。它将负责从本地存储或互联网加载所有图像。

https://github.com/nostra13/Android-Universal-Image-Loader

答案 2 :(得分:0)

OutOfMemory可能很累人 这里有几个你可以看的选项

try { 
     //Create your bitmap here 

} catch (OutOfMemoryError ooM) {
        // You got out of memory now do something to recycle images
                    // Yes you can catch OOM.
        recycle();
}

如果你没有很多图像需要处理,那么你可以试试这个。

    BitmapFactory.Options op = new BitmapFactory.Options();
    op.inSampleSize = 8;
    return BitmapFactory.decodeFile("<YOUR IMAGE FILE HERE>", op);

如果你有很多图像

,上面的组合会很有用