java.lang.OutOfMemoryError同时在库中显示图像

时间:2013-12-17 14:11:53

标签: android android-gallery

当我从SD卡加载图像时,我得到了例外

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

这是我的代码:

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

1 个答案:

答案 0 :(得分:0)

当您加载大型位图文件时,BitmapFactory类提供了几种解码方法(decodeByteArray(),decodeFile(),decodeResource()等。)。

第1步

在解码时将inJustDecodeBounds属性设置为true可避免内存分配,为位图对象返回null但设置outWidth,outHeight和outMimeType。此技术允许您在构造(和内存分配)位图之前读取图像数据的尺寸和类型。

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.

第2步

告诉解码器对图像进行二次采样,将较小的版本加载到内存中,在BitmapFactory.Options对象中将inSampleSize设置为true。

例如,使用inSampleSize为4解码的分辨率为2048x1536的图像会产生大约512x384的位图。将其加载到内存中对于完整图像使用0.75MB而不是12MB。

这是一种根据目标宽度和高度计算样本大小值为2的幂的方法:

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

请阅读此链接了解详情。 http://developer.android.com/training/displaying-bitmaps/load-bitmap.html