如何克服这种错误:java.lang.OutOfMemoryError:位图大小超过VM预算 [英] How to overcome this error:java.lang.OutOfMemoryError: bitmap size exceeds VM budget

查看:80
本文介绍了如何克服这种错误:java.lang.OutOfMemoryError:位图大小超过VM预算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想补充SQLite中DB的图像和上市的图像从数据库到ListView的....我存储图像路径来获得图像。 当我在设备列表中选择图像从DB我得到的错误,如 java.lang.OutOfMemoryError:位图大小超过VM预算

I am trying to add images in Sqlite DB and listing the images from DB to listview.... I am storing the image path to get image. When I list the images from DB in device I am getting error like java.lang.OutOfMemoryError: bitmap size exceeds VM budget

我是否清楚堆内存每次。 如何纠正这种..这是我的code。

Do I clear heap memory every time. How to correct this.. Here is my code.

LView.class

LView.class

mySQLiteAdapter = new SQLiteAdapter(this);
mySQLiteAdapter.openToWrite();                
mAlbum = (ImageView) findViewById(R.id.iv);
mAlbum.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_PICK, 
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, IMG);
}
});

Button click = (Button) findViewById(R.id.button);
click.setOnClickListener(new OnClickListener() {
@Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        mySQLiteAdapter.insert(str);
        System.out.println(str+" Added");
        Intent intent = new Intent(LView.this, MyList.class);
        startActivity(intent);              
    }
});`

`

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);
    switch(requestCode) {

    case 1: 
        if(resultCode == RESULT_OK) {
            Uri selectedUri = data.getData();
            str = getPath(selectedUri);
            Bitmap bitmap;              
            try {                   
                bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedUri));
                mAlbum.setImageBitmap(bitmap);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;
            }
        }
}
// Converting image path Uri to String path to store in DB
    public String getPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cur = managedQuery(uri, projection, null, null, null);
        int columnIndex = cur.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cur.moveToFirst();

        return cur.getString(columnIndex);
    }`

请建议我... 先谢谢了。

Pls suggest me... Thanks in advance.

推荐答案

您获得图像的实际大小为prevent的OOM问题。永远不要去code中的形象第一次!

1) try to decode the image bound first

you get the actual size of the image to prevent the OOM issue. Dont ever decode the image first!!!

    BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;

BitmapFactory.decodeByteArray(bitmapByteArray, 0, bitmapByteArray.length, options);'

options.outWidth和options.outHeight是你想要的。

options.outWidth and options.outHeight are what you want.

通过使用从以下code <一href="http://hi-android.info/src/com/android/camera/Util.java.html">http://hi-android.info/src/com/android/camera/Util.java.html.如果您发现该outWidth和outHeight太大,有OOM问题,只需设置outWidth和outHeight以更小的尺寸。它会给你去codeD映像将被设置为那些outWidth和outHeight样本大小。这里的位图选项是在步骤1中使用相同的。

by using the following code from http://hi-android.info/src/com/android/camera/Util.java.html. If you detect the outWidth and outHeight are too big to have OOM issue, just set the outWidth and outHeight to a smaller size. It will give you a sample size that the decoded image will be set to those outWidth and outHeight. The bitmap options here is the same you use in step 1.

    private static int computeInitialSampleSize(BitmapFactory.Options options,
        int minSideLength, int maxNumOfPixels) {
    double w = options.outWidth;
    double h = options.outHeight;

    int lowerBound = (maxNumOfPixels == IImage.UNCONSTRAINED) ? 1 :
            (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
    int upperBound = (minSideLength == IImage.UNCONSTRAINED) ? 128 :
            (int) Math.min(Math.floor(w / minSideLength),
            Math.floor(h / minSideLength));

    if (upperBound < lowerBound) {
        // return the larger one when there is no overlapping zone.
        return lowerBound;
    }

    if ((maxNumOfPixels == IImage.UNCONSTRAINED) &&
            (minSideLength == IImage.UNCONSTRAINED)) {
        return 1;
    } else if (minSideLength == IImage.UNCONSTRAINED) {
        return lowerBound;
    } else {
        return upperBound;
    }
}

3)通过计算样本量

一旦你的样本量,用它去code真实的图像数据。

3) Use the computed sample size

Once you get the sample size, use it to decode the real image data.

            options.inTempStorage = new byte[16*1024];
        options.inPreferredConfig = (config == null)?BitmapUtil.DEFAULT_CONFIG:config;
        options.inSampleSize = BitmapUtil.computeSampleSize(bitmapWidth, bitmapHeight, bitmapWidth < bitmapHeight?targetHeight:targetWidth, bitmapWidth < bitmapHeight?targetWidth:targetHeight, 1);
        options.inPurgeable = true;  
        options.inInputShareable = true;  
        options.inJustDecodeBounds = false;
        options.inDither = true;
        result = BitmapFactory.decodeByteArray(bitmapByteArray, 0, bitmapByteArray.length, options);

〜如果这仍然给你OOM问题,您可以尝试降低outWidth和outHeight。 位图是使用原生堆,而不是Java堆。因此,它是很难检测到多少内存的新形象去codeD就走了。

~If this still give you OOM issue, you can try to lower the outWidth and outHeight. bitmap is using native heap, not the java heap. So it is hard to detect how much memory left for the new image decoded.

~~如果你有到outWidth和outHeight设置得太低,则可能有内存泄漏的地方在code。尝试释放从内存,你不使用任何对象。 例如bitmap.release();

~~If you have to set the outWidth and outHeight too low, then you may have memory leak somewhere in your code. try to release any object from memory that you dont use. e.g bitmap.release();

~~~上面的只是一个样本code。调整你所需要的。

~~~the above is just a sample code. adjust what you need.

这篇关于如何克服这种错误:java.lang.OutOfMemoryError:位图大小超过VM预算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆