Search code examples
androidandroid-imageviewout-of-memoryandroid-imagebitmapfactory

OutOfMemoryError when using bitmapfactory with TouchImageView


I'm trying to make a fragment which would show a zoomable image using TouchImageView(https://github.com/MikeOrtiz/TouchImageView)

The fragment also has a spinner for changing images. The problem is that the first image loads ok, but when i use the scroller to change the image, I get an OutOfMemoryError and the program crashes. Here's my code

public class mapFragment extends SherlockFragment {


String[] Levels = { "Ground Floor", "First Floor",
        "Second Floor", "Third Floor"
};

Button button;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved)
{
    View v = inflater.inflate(R.layout.maps_layout, group, false);


    final TouchImageView img = (TouchImageView) v.findViewById(R.id.touchimage1);
    final Bitmap snoop = BitmapFactory.decodeResource(getResources(), R.drawable.groundfloor);
    img.setImageBitmap(snoop);




    final Spinner s = (Spinner) v.findViewById(
            R.id.spinnerlevels);

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this
            .getActivity().getBaseContext(),
            android.R.layout.simple_spinner_item, Levels);
    s.setAdapter(adapter);

    s.setOnItemSelectedListener(new OnItemSelectedListener() {

        public void onItemSelected(AdapterView<?> parent, View view, 
                int pos, long id) {
            // An item was selected. You can retrieve the selected item using
            // parent.getItemAtPosition(pos)
            int item = s.getSelectedItemPosition();



            if(item ==0){
                snoop.recycle();
                Bitmap snoop = BitmapFactory.decodeResource(getResources(), R.drawable.groundfloor);
                img.setImageBitmap(snoop);
            }
            if(item ==1){
                snoop.recycle();
                Bitmap snoop = BitmapFactory.decodeResource(getResources(), R.drawable.firstfloor);
                img.setImageBitmap(snoop);
            }
            if(item ==2){
                snoop.recycle();
                Bitmap snoop = BitmapFactory.decodeResource(getResources(), R.drawable.secondfloor);
                img.setImageBitmap(snoop);
            }
            if(item ==3){
                snoop.recycle();
                Bitmap snoop = BitmapFactory.decodeResource(getResources(), R.drawable.thirdfloor);
                img.setImageBitmap(snoop);
            }


        }

        public void onNothingSelected(AdapterView<?> parent) {
            // Another interface callback
        }
    });



    img.setMaxZoom(8f);

    return (v);


}

}

Shouldn't "recylce()" remove the first image, to give place to the new one in the memory? The images sizes in MB are 1.4, 1.5, 1.5, 1.3


Solution

  • For each pixel of your image your heap use 8 bytes. Now how much memory is 1754 x 2481 x 8? The answer is 32.94 MB of heap memory. On many devices you wont have more than 16 MB heap which is used for other stuff as well. Do you get your problem now?

    You need to make the images smaller or your app will never fly :)