2015-02-09 65 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