2015-02-09 66 views
0

我得到的OutOfMemoryError位图,同时呼吁Bitmap.createScaledBitmap获取的OutOfMemoryError位图在Android中

我已经尝试过回收并设置为null位图的参考,但仍stucked。我现在用

代码是

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) 

在此先感谢。

+0

请参阅官方的Android位图参考http://developer.android.com/training/displaying-bitmaps/index.html – 2015-02-09 08:25:45

+0

这可能会回答你的问题:http://stackoverflow.com/questions/15552076/android- bitmap-creatingcaledbitmap-throws-java-lang-outofmemoryerror-mostly-on-je – IntegralOfTan 2015-02-09 08:27:51

+0

来看看[link](http://stackoverflow.com/a/823966/4385913) – 2015-02-09 08:32:17

回答

0

我不知道你在做什么,但我会建议你使用一个库,例如http://square.github.io/picasso/。在Android中加载和处理位图可能非常困难并且非常耗时。有了这个库,你可以免费获得缓存等。

你的位图有多大?您可以进行各种优化,正如在评论中给您的链接中所解释的。例如:减小图像大小(从我能看到的是在第一行中加载位图完整大小),减少色彩空间(如果你不需要一个alpha通道,例如,这会节省几个字节)。根据您的使用情况,请查看http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html了解如何优化位图加载的选项。

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

1

这不是因为回收或设置为空bitmap。这是因为你的Image太大。我可以从你的代码中看到:

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

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

要解决该问题,您可以访问Loading Large Bitmap effeciently以了解如何在显示位图之前缩小位图。

0

我相信这是因为即使您加载的位图对于您测试项目的设备来说都很大,或者您没有摆脱已使用的位图,因此您的位图已经重载,或者您有两个问题,所以,当访问低内存的设备时,考虑按比例缩放您的位图以符合该设备的内存条件,根据我的回答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