在Android的位图factory.de $ C $的CFile java.lang.outofmemory错误位图、错误、de、factory

2023-09-07 10:08:52 作者:你是我的♂大男人

首先,我打电话MediaStore.ACTION_IM​​AGE_CAPTURE意图打开相机,然后我从这个函数得到保存拍摄的图像的路径。

 私人字符串getLastImageId(){    的String [] = imageColumns {MediaStore.Images.Media._ID,MediaStore.Images.Media.DATA};    字符串imageOrderBy = MediaStore.Images.Media._ID +DESC;    光标imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,imageColumns,NULL,NULL,imageOrderBy);    如果(imageCursor.moveToFirst()){        INT ID = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));        字符串FULLPATH = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));        //imageCursor.close();        返回完整路径;    }其他{        返回;    }} 

然后我传递路径,一个产品对象的属性作为参数。这个对象添加到产品列表该列表是由一个定制适配器显示。我正在显示产品名称和形象在ListView

在自定义适配器类我得到的产品从中获取产品名称和路径从路径使位图,它ASIGN到产品托座包含一个图像视图这种方式工作的第一张照片是好的,但在第二张照片,它给java.lang.outofmemory的例外,我也试图在

给出的解决方案

java.lang.OutOfMemoryError:位图大小超过VM预算 - Android电子

这样在产品的适配器

 公共类ProductAdopter扩展ArrayAdapter<产品与GT; {上下文语境;INT layoutResourceId;ArrayList的<产品与GT;数据= NULL;公共ProductAdopter(上下文的背景下,诠释layoutResourceId,ArrayList的<产品与GT; product_data){    // TODO自动生成构造函数存根    超(背景下,layoutResourceId,product_data);    this.layoutResourceId = layoutResourceId;    this.context =背景;    this.data = product_data;}@覆盖公共查看getView(INT位置,查看convertView,父母的ViewGroup){    查看排= convertView;    ProductHolder支架=无效;    如果(行== NULL)    {        LayoutInflater充气=((MainActivity)上下文).getLayoutInflater();        行= inflater.inflate(layoutResourceId,父母,假);        持有人=新ProductHolder();        holder.imgIcon =(ImageView的)row.findViewById(R.id.imgIcon);        holder.txtTitle =(TextView中)row.findViewById(R.id.txtTitle);        row.setTag(保持器);    }    其他    {        支架=(ProductHolder)row.getTag();    }    产品产品= data.get(位置);    holder.txtTitle.setText(product.getName());    文件imgFile =新的文件(product.icon);    如果(imgFile.exists()){        位图MYBITMAP = BitmapFactory.de codeFILE(imgFile.getAbsolutePath());        holder.imgIcon.setImageBitmap(MYBITMAP);        //myBitmap.recycle();    }    返回行;}静态类ProductHolder{    ImageView的imgIcon;    TextView的txtTitle;}} 
vscode的C 开发环境配置 win10下Linux子系统

解决方案

 如果(imgFile.exists()){    最后BitmapFactory.Options选项=新BitmapFactory.Options();    options.inSampleSize = 8;   位图MYBITMAP = BitmapFactory.de codeFILE(imgFile.getAbsolutePath(),选件);        holder.imgIcon.setImageBitmap(MYBITMAP);        //myBitmap.recycle();    } 

使用inSampleSize加载尺度位图到内存。使用2的幂为inSampleSize值是去codeR更快,更高效。但是,如果您打算缓存大小版本内存或磁盘上,它通常是仍然值得解码到最合适的图像尺寸,以节省空间。

有关更多见装载大位图高效

First i call MediaStore.ACTION_IMAGE_CAPTURE intent to open camera then i get the saved captured image path from this function.

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 "";
    }
}

then i pass that path to a product object attribute as a parameter. add that object to product list that list is displayed by a customized adapter. i am displaying the product title and image in the listView

in customized adapter class i get the product fetch product title and path from it make a bitmap from path and asign it to the product holder that contain a image view working this way for first photo is fine but on the second photo it gives the exception of java.lang.outofmemory i have also tried the solution given at

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

doing so as in product adapter

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;
}
}

解决方案

 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();
    }

Use inSampleSize to load scales bitmaps to memory. Using powers of 2 for inSampleSize values is faster and more efficient for the decoder. However, if you plan to cache the resized versions in memory or on disk, it’s usually still worth decoding to the most appropriate image dimensions to save space.

For more see Loading Large Bitmaps Efficiently