-3

When i was loading images form sd card i got the exception

java.lang.OutOfMemoryError at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)

Here is my code:

    public class Images extends Activity implements OnItemLongClickListener {
        private Uri[] mUrls;
        String[] mFiles = null;
        ImageView selectImage;
        Gallery g;
        static final String MEDIA_PATH = new String("/mnt/sdcard/DCIM/Camera/");

        @Override
        public void onCreate(Bundle icicle) {

            super.onCreate(icicle);
            setContentView(R.layout.main);
            selectImage = (ImageView) findViewById(R.id.image);
            g = (Gallery) findViewById(R.id.gallery);
            File images = new File(MEDIA_PATH);
            Log.i("files", images.getAbsolutePath());

            File[] imagelist = images.listFiles(new FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    return ((name.endsWith(".jpg")) || (name.endsWith(".png")));
                }
            });
            Log.i("files", imagelist.toString());
            String[] mFiles = null;
            mFiles = new String[imagelist.length];

            for (int i = 0; i < imagelist.length; i++) {
                mFiles[i] = imagelist[i].getAbsolutePath();
            }
            System.out.println(mFiles.length);

            mUrls = new Uri[mFiles.length];
            System.out.println(mUrls.length);
            for (int i = 0; i < mFiles.length; i++) {
                mUrls[i] = Uri.parse(mFiles[i]);
            }

            g.setAdapter(new ImageAdapter(this));


    //      g.setOnItemSelectedListener(this);
            g.setOnItemLongClickListener(this);



        }

        public class ImageAdapter extends BaseAdapter {

            // int mGalleryItemBackground;

            public ImageAdapter(Context c) {
                mContext = c;
            }

            public int getCount() {
                return mUrls.length;
            }

            public Object getItem(int position) {
                return position;
            }

            public long getItemId(int position) {
                return position;
            }

            public View getView(int position, View convertView, ViewGroup parent) {
                Log.i("ok5", "ok");
                ImageView i = new ImageView(mContext);

                i.setImageURI(mUrls[position]);
                Log.i("ok", "ok");
                i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
                i.setLayoutParams(new Gallery.LayoutParams(100, 100));
                return i;
            }

            private Context mContext;
        }

        @Override
        public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // TODO Auto-generated method stub

            selectImage.setImageURI(mUrls[arg2]);
            System.out.println("path: "+mUrls[arg2]);

            Uri f = mUrls[arg2];
            File f1 = new File(f.toString());
            System.out.println("f1: "+f1);
            return false;
        }
Aleks G
  • 56,435
  • 29
  • 168
  • 265

1 Answers1

0

While you load large bitmap files, BitmapFactory class provides several decoding methods (decodeByteArray(), decodeFile(), decodeResource(), etc.).

STEP 1

Setting the inJustDecodeBounds property to true while decoding avoids memory allocation, returning null for the bitmap object but setting outWidth, outHeight and outMimeType. This technique allows you to read the dimensions and type of the image data prior to construction (and memory allocation) of the bitmap.

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
To avoid java.lang.OutOfMemory exceptions, check the dimensions of a bitmap before decoding it.

STEP 2

To tell the decoder to subsample the image, loading a smaller version into memory, set inSampleSize to true in your BitmapFactory.Options object.

For example, an image with resolution 2048x1536 that is decoded with an inSampleSize of 4 produces a bitmap of approximately 512x384. Loading this into memory uses 0.75MB rather than 12MB for the full image.

Here’s a method to calculate a sample size value that is a power of two based on a target width and height:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
    int reqWidth, int reqHeight) {

// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);

// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}

public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

    final int halfHeight = height / 2;
    final int halfWidth = width / 2;

    // Calculate the largest inSampleSize value that is a power of 2 and keeps both
    // height and width larger than the requested height and width.
    while ((halfHeight / inSampleSize) > reqHeight
            && (halfWidth / inSampleSize) > reqWidth) {
        inSampleSize *= 2;
    }
}

return inSampleSize;
}

Please read this link for details. http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

nitesh goel
  • 6,338
  • 2
  • 29
  • 38