【问题标题】:Getting OutOfMemoryError on BitMap in android在android中的BitMap上获取OutOfMemoryError
【发布时间】:2015-02-09 08:25:02
【问题描述】:

在调用 Bitmap.createScaledBitmap 时,我在 BitMap 上遇到 OutOfMemoryError

我已经尝试回收并将位图引用设置为空,但仍然卡住。

我使用的代码是

private Bitmap getImageBitmap(float startX, float startY, float currX, float currY, Resources res, int resId) {
    Bitmap bitSrc = BitmapFactory.decodeResource(res, resId);
    int dstWidth = (int) ((Math.abs((currX - startX)) + 1));
    int dstHeight = (int) ((Math.abs((currY - startY)) + 1));
    Bitmap bitImg = Bitmap.createScaledBitmap(bitSrc, dstWidth, dstHeight, false);
    bitSrc = null;
    return bitImg;
}

我正在画布上设置返回的 bitImg。 这是我的日志文件

    08-14 13:31:14.364: E/AndroidRuntime(6714): java.lang.OutOfMemoryError
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.graphics.Bitmap.nativeCreate(Native Method)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.graphics.Bitmap.createBitmap(Bitmap.java:809)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.graphics.Bitmap.createBitmap(Bitmap.java:786)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.graphics.Bitmap.createBitmap(Bitmap.java:718)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:594)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at com.example.layout.Drawing.getImageBitmap(DrawingSurface.java:856)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at com.example.layout.Drawing.onDraw(DrawingSurface.java:291)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.draw(View.java:14465)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13362)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13404)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13300)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13404)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13300)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13404)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13300)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13404)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13300)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13404)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3077)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13300)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.View.getDisplayList(View.java:13404)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.HardwareRenderer$GlRenderer.buildDisplayList(HardwareRenderer.java:1626)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1505)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.ViewRootImpl.draw(ViewRootImpl.java:2460)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2332)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1962)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1079)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5784)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:774)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.Choreographer.doCallbacks(Choreographer.java:587)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.Choreographer.doFrame(Choreographer.java:550)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:760)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.os.Handler.handleCallback(Handler.java:733)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.os.Handler.dispatchMessage(Handler.java:95)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.os.Looper.loop(Looper.java:136)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at android.app.ActivityThread.main(ActivityThread.java:5017)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at java.lang.reflect.Method.invokeNative(Native Method)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at java.lang.reflect.Method.invoke(Method.java:515)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
08-14 13:31:14.364: E/AndroidRuntime(6714):     at dalvik.system.NativeStart.main(Native Method)

提前致谢。

【问题讨论】:

标签: android bitmap


【解决方案1】:

这不是因为回收或设置 null bitmap。这是因为你的Image 太大了。从您的代码中可以看出:

位图bitSrc = BitmapFactory.decodeResource(res, resId);

您加载一次大的Bitmap,然后再加载一次Bitmap.createScaledBitmap(bitSrc, dstWidth, dstHeight, false);。这意味着你加载了两倍大的Image --> 这就是你得到outofmemory 异常的原因。

要解决这个问题,您可以访问Loading Large Bitmap effeciently 了解如何在显示位图之前按比例缩小它。

【讨论】:

    【解决方案2】:

    我不知道您要达到什么目的,但我建议您使用库,例如​​ http://square.github.io/picasso/。在 Android 中加载和处理位图可能既困难又耗时。使用这个库,您可以免费获得缓存等。

    您的位图有多大?您可以进行各种优化,如 cmets 中提供给您的链接中所述。例如:减小图像大小(从我可以看到您在第一行加载位图全尺寸),减小颜色空间(例如,如果您不需要 alpha 通道,这将为您节省几个字节)。查看http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html,了解如何根据您的使用优化位图加载。

    我再次建议您使用解决所有这些问题的库,Android 中的位图很难。

    【讨论】:

      【解决方案3】:

      查看有关此问题的开发人员指南: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

      它指出您必须通过添加加载尺寸而不是位图本身的 BitmapFactory.Options 来获取位图的尺寸。使用这些尺寸,您可以计算所需位图的比例大小。将该比例添加到 BitmapFactory.Options 并以正确的大小加载位图。

      【讨论】:

        【解决方案4】:

        我相信这是因为即使您加载的位图对于您在其上测试项目的设备来说也太大了,或者您没有摆脱使用过的位图,因此您的位图过载,或者您甚至有这两个问题,所以,访问内存不足的设备时,请考虑缩放位图以满足该设备的内存条件,根据我的回答here,您必须使用以下方式来缩放您的位图(您没有发布您使用的方式):

        // to scale your Bitmaps
        // assign newWidth and newHeight with the corresponding width and height that doesn't make your memory overloads and in the same time doesn't make your image loses it's Features
        private Bitmap scaleBitmap(Bitmap bitmapToScale, float newWidth, float newHeight) {
        
            if(bitmapToScale == null)
                return null;
            //get the original width and height
            int width = bitmapToScale.getWidth();
            int height = bitmapToScale.getHeight();
            // create a matrix for the manipulation
            Matrix matrix = new Matrix();
        
            // resize the bit map
            matrix.postScale(newWidth / width, newHeight / height);
        
            // recreate the new Bitmap and set it back
            return Bitmap.createBitmap(bitmapToScale, 0, 0, bitmapToScale.getWidth(), bitmapToScale.getHeight(), matrix, true);  
        
        }
        

        并摆脱使用过的资源,如下所示:

        bitSrc.recycle(); you source Bitmap
        stream.close(); // if you used to load the Bitmap
        stream = null;
        bitmap.recycle(); // your used Bitmap after using it
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-11
          • 1970-01-01
          • 2011-02-07
          相关资源
          最近更新 更多