BitMap图像Out of Memory Android

时间:2013-12-04 06:27:00

标签: java android bitmap out-of-memory

我的虚拟杂志中有数百张图片。图像为1241* 1754像素,分辨率为150 pixels/inch。滑动到这些页面的3/4后,我得到了内存不足错误,如日志中所示。

12-04 10:20:50.781: E/AndroidRuntime(3236): java.lang.OutOfMemoryError
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:572)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:440)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.content.res.Resources.loadDrawable(Resources.java:1974)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.content.res.Resources.getDrawable(Resources.java:677)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at fi.harism.curl.LPMagHome$PageProvider.loadBitmap(LPMagHome.java:192)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at fi.harism.curl.LPMagHome$PageProvider.updatePage(LPMagHome.java:266)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at fi.harism.curl.CurlView.updatePage(CurlView.java:713)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at fi.harism.curl.CurlView.startCurl(CurlView.java:554)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at fi.harism.curl.CurlView.onTouch(CurlView.java:280)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.View.dispatchTouchEvent(View.java:5583)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1968)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1695)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1968)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1695)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1968)

*

以下是我加载位图图像的工作的一部分。有人可以帮助我如何处理这个内存不足的错误,通过一些研究我看到了这个博客java.lang.OutOfMemoryError BitmapFactory.nativeDecodeAsset(),但我无法将其应用于下面的方法loadBitmap。

private Bitmap loadBitmap(int width, int height, int index) {
            Bitmap b = Bitmap.createBitmap(width, height,
                    Bitmap.Config.ARGB_8888);
            b.eraseColor(0xFFFFFFFF);
            c = new Canvas(b);
            d = getResources().getDrawable(mBitmapIds[index]);
            System.out.println("canvas width: "+c.getWidth());

            int margin = 3;//7
            int border = 3;//2
            Rect r = new Rect(margin, margin, width - margin, height - margin);
            int imageWidth = r.width() - (border * 2);
            int imageHeight = imageWidth * d.getIntrinsicHeight()
                    / d.getIntrinsicWidth();
            if (imageHeight > r.height() - (border * 2)) {
                imageHeight = r.height() - (border * 2);
                imageWidth = imageHeight * d.getIntrinsicWidth()
                        / d.getIntrinsicHeight();
            }
            Log.d("TAG", String.valueOf(imageHeight));
            if (lp.getWindow().getWindowManager().getDefaultDisplay()
                    .getOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
                // portrait mode
                r.left += ((r.width() - imageWidth) / 2) - border;
                r.right = r.left + imageWidth + border + border;
            } else if (lp.getWindow().getWindowManager().getDefaultDisplay()
                    .getOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
                // landscape
                r.left += ((r.width() - imageWidth)) - border-122;
                r.right = r.left + imageWidth + border + border+122;
            }
            r.top += ((r.height() - imageHeight) / 2) - border;
            r.bottom = r.top + imageHeight + border + border;
            Paint p = new Paint();
            p.setColor(0xFFC0C0C0);
            c.drawRect(r, p);
            r.left += border;
            r.right -= border;
            r.top += border;
            r.bottom -= border;
            d.setBounds(r);
            d.draw(c);
            return b;
        }*

更新:使用此方法滑动时页面会更新

@覆盖         public void updatePage(CurlPage page,int width,int height,int index){

        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int wwidth = displaymetrics.widthPixels;
        int hheight = displaymetrics.heightPixels;


        if(wwidth > hheight){

            System.out.println("index "+(index*2));
            System.out.println("index2 "+(index*2)+1);
            System.out.println("case landscape orientation...");

            if (index >0){

                front = loadBitmap(width, height, (index*2));
                back = loadBitmap(width, height, (index*2)+1);

            }else {

                front = loadBitmap(width, height, (index));
                back = loadBitmap(width, height, (index));
            }

            Matrix matrix = new Matrix(); 
            matrix.preScale(-1.0f, 1.0f); 
            Bitmap mirroredBitmap = Bitmap.createBitmap(back, 0, 0, back.getWidth(), back.getHeight(), matrix, false);

            page.setTexture(front, CurlPage.SIDE_FRONT);
            page.setTexture(mirroredBitmap, CurlPage.SIDE_BACK);



        } else {

            System.out.println("case portrait orientation...");
            Bitmap front = loadBitmap(width, height, index);
            Bitmap back = loadBitmap(width, height, index);

            System.out.println( "MyActivity.onCreate debug message "+String.valueOf(index));

            page.setTexture(front, CurlPage.SIDE_FRONT);
            page.setTexture(back, CurlPage.SIDE_BACK);

        }

    }

}

5 个答案:

答案 0 :(得分:2)

你正在泄露记忆。通过删除对它的所有引用来检查您是否释放了内存以避免此问题。另外请记住,某些设备没有太多内存,因此您需要使用更少的内存。

另请参阅我对how to find memory leaks的回答。

答案 1 :(得分:2)

您可能需要调整位图的大小。我也遇到了这个问题并通过以下代码解决了这个问题:

public static Bitmap getResizedBitmap(Bitmap image, int newHeight, int newWidth) {
    int width = image.getWidth();
    int height = image.getHeight();
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    // create a matrix for the manipulation
    Matrix matrix = new Matrix();
    // resize the bit map
    matrix.postScale(scaleWidth, scaleHeight);
    // recreate the new Bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap(image, 0, 0, width, height,
            matrix, false);
    return resizedBitmap;
}

答案 2 :(得分:1)

在玩大量图片时这是一个普遍的问题。尼基塔我建议你使用一个api库,负责加载图像,清除图像不在时的缓存和其他必要的东西。 Here是github项目的链接,下载jar并将其添加到项目的libs文件夹中。

配置图像检查this

答案 3 :(得分:1)

可能有内存泄漏。如果该位图没有进一步使用,您可以调用bitmap.recycle()来节省内存。此外,您可以尝试缩小位图:

Bitmap scale_down = Bitmap.createScaledBitmap(original_bmp, original_bmp.getWidth()/2, original_bmp.getHeight()/2, true);

答案 4 :(得分:0)

我没有看到你的所有代码,所以我只能假设你将所有图像都放入内存中。我可以把屏幕上显示的图像放到内存中,而另一个图像从内存释放,这种方式可以实现并减少占用的内存。请阅读:Strange out of memory issue while loading an image to a Bitmap object

我很抱歉我的英语不好!