1

I have made an android application where image will save to local database when the network is unavailable. I am keeping image uri inside database table and retrieving image from image uri and showing that image on imageView of a listView using Custom array adapter. When I am running my application with emulator, it is working well. However while using an android mobile phone it showing Forced Close error.

The error log is given below:

java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:504)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:370)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:715)
at android.graphics.drawable.Drawable.createFromStream(Drawable.java:675)
at android.widget.ImageView.resolveUri(ImageView.java:525)
at android.widget.ImageView.setImageURI(ImageView.java:309)
at com.freedom.net.Syncho2$NoteListAdapter.getView(Syncho2.java:219)
at android.widget.AbsListView.obtainView(AbsListView.java:1519)
at android.widget.ListView.makeAndAddView(ListView.java:1749)
at android.widget.ListView.fillDown(ListView.java:674)
at android.widget.ListView.fillFromTop(ListView.java:731)
at android.widget.ListView.layoutChildren(ListView.java:1602)
at android.widget.AbsListView.onLayout(AbsListView.java:1349)
at android.view.View.layout(View.java:7320)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1263)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1137)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1051)
at android.view.View.layout(View.java:7320)
at android.widget.FrameLayout.onLayout(FrameLayout.java:342)
at android.view.View.layout(View.java:7320)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1263)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1137)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1051)
at android.view.View.layout(View.java:7320)
at android.widget.FrameLayout.onLayout(FrameLayout.java:342)
at android.view.View.layout(View.java:7320)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1162)

MY Custom adapter is given below:

public class NoteListAdapter extends  ArrayAdapter<ImageFromDB> {
Context c;

ArrayList<ImageFromDB> image = null;
ArrayList<String> uriImage = null;
ArrayList<Integer> ID = null;

private AllId allid = null;
DBAdapter db = null;

WatchListAllEntity watchListAllEntity=null;
int flagVariable=1;
private ArrayList<ImageFromDB> items;

public NoteListAdapter(Context context, int textViewResourceId,
        ArrayList<ImageFromDB> items) {

    super(context, textViewResourceId, items);
    Log.e("sf","123");
    this.items = items;
    c=context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;

    final int myPosition = position;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.listitempict2, null);
    }
    ImageFromDB re = items.get(position);
    Log.e("re", re+"");
    if (re != null) {
        ImageView tt = (ImageView) v.findViewById(R.id.imageviewproduct);
        String imageUri = re.getImageuri();
        Log.e("imageUri", imageUri+"");
        tt.setImageURI(Uri.parse(imageUri));

        final CheckBox checkBox = (CheckBox) v.findViewById(R.id.checkboxproduct);
        checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {

                if (isChecked) {
                    if(flagVariable==1)
                    {
                        String ImUri = items.get(myPosition).getImageuri();
                        allid.setImageUri(ImUri);
                        allid.setId(items.get(myPosition).getId());
                        flagVariable++;
                        Log.e("flagVariable  : " , flagVariable+"");
                    }
                    else
                    {
                        checkBox.setChecked(false);
                        //Toast.makeText(Syncho2.this,"正しく選んでください。",Toast.LENGTH_SHORT).show();
                    }
                } else {
                    flagVariable=1;
                    Log.e("flagVariable  : " , flagVariable+"");
                }
            }
        });
    }
    return v;
}
}

I am calling this Adapter from a activity like this:

noteListAdapter = new NoteListAdapter(this, R.layout.listitempict, image);

I noticed from debug, the Adapter is being called six times when the image is only two . Five times it's returning a view but on the sixth time it is showing that error.

0

3 Answers 3

2

Read this: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html and you'll be able to load your image without any error!

Sign up to request clarification or add additional context in comments.

3 Comments

i'm sure that compressing the bitmap will not fully help in this case - the app will forceclose not on the sixs' time but on the 16s' (for exmaple) =)
It's not about the compressing, it's about loading a scaled down version of the image. On the scree you don't need to display a 8Mp image. Just load the image scaled down to your screen size.
"I noticed from debug ,the Adapter is calling six times when the image is only two" - as you see even if he make this images smaller the problem is not only in scaled image, it will help only not to fall on the sixs' step - but it will forceclose after some time.
0
 public View getView(int position, View convertView, ViewGroup parent) {        

        View row = convertView;
     // if it's not recycled, initialize some attributes
        if (row == null) {  
            LayoutInflater li = (LayoutInflater)   mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
            row = li.inflate(R.layout.menucategory, null);          
            //imageView.setLayoutParams(new GridView.LayoutParams(85, 85));         
        }
            // getCategoryItem          
            Category  category = (Category) getItem(position);
            // Get reference to ImageView
            categoryIcon = (ImageView) row.findViewById(R.id.category_image);
            //categoryIcon.setLayoutParams(new GridView.LayoutParams(85, 85));
            categoryIcon.setScaleType(ImageView.ScaleType.CENTER_CROP);
            categoryIcon.setPadding(5, 5, 5, 5);

            categoryName = (TextView) row.findViewById(R.id.category_name);
            //Set category name
            categoryName.setText(category.getCategoryName());           


            if(category.getCategoryPath() != null){             
                    Bitmap bitmap = BitmapFactory.decodeFile(category.getCategoryPath());
                    System.out.println("bitmap2::  "+ bitmap);
                    if(bitmap != null){
                     categoryIcon.setImageBitmap(bitmap);
                    }               
            }                              

        return row;
    }

Comments

0

I have found a solution . I thing everybody should know about memory management of android application. http://www.youtube.com/watch?v=_CruQY55HOk . When I am trying to show image Uri directly on ImageView then the problem is creating . I thing everybody should avoid code like this ImageView.setImageURI(Uri.parse(imageUri)) . Instead of that, try to load bitmap or drawable on imageview.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.