user2274314
user2274314

Reputation: 75

java.lang.outofmemory error at bitmap factory.decodefile in Android

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

Upvotes: 1

Views: 3485

Answers (3)

Its not blank
Its not blank

Reputation: 3095

OutOfMemory can be tiring here are some few options that you can look

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

If you do not have many images to handle then you can try this.

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

A combination of above can be useful if you have many images

Upvotes: 0

Arun C
Arun C

Reputation: 9035

 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

Upvotes: 5

Sharjeel
Sharjeel

Reputation: 15798

You will run into out of memory issues if you try to decode big images yourself.

Try using Universal Image loader. It will take care of all image loading from local storage or the internet.

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

Upvotes: 0

Related Questions