2013-02-13 71 views
0

我在我的應用程序有問題。在landpace模式下切換時,會調用setContentView()方法來顯示鋼琴鍵盤。鋼琴鍵盤類擴展Surfaceview以獲得更好的性能,顯示按下的鍵。在一個位圖陣列與BitmapFactory.decodeResource()方法,並保持位圖,直到應用程序被破壞內存異常與位圖

RelativeLayout rootLayout = (RelativeLayout) findViewById(R.id.rootLayout); 
RelativeLayout.LayoutParams relativeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
relativeLayoutParams.addRule(RelativeLayout.BELOW, R.id.relativeLayoutLowerBar); 
rootLayout.addView(keyboardSurfaceView, relativeLayoutParams); 

在我keyboardSurfaceView類IM裝載位圖:這個SurfaceView類作爲子項添加到我的景觀佈局。這很好。當以縱向模式IM swiching,更改與佈局的setContentView()和刪除keyboardSurfaceView:

if(keyboardSurfaceView != null && keyboardSurfaceView.getParent() != null) 
     ((ViewGroup) keyboardSurfaceView.getParent()).removeView(keyboardSurfaceView); 

位圖被加載一次。第一次切換到橫向模式時。我遇到了一個內存不足的錯誤,當它從風景中的燈光照亮10-20倍時,當我更新ddms視圖中的堆時,我可以看到,每當我從橫向視圖中的protrait視圖切換時,堆大小都會增長到約。 20mb然後應用程序崩潰。我不知道爲什麼這一直在發生。位圖只加載一次,而不是每次都加載。 我也試過bitmap.recycle(); bitmap = null沒有成功。也嘗試按照Google最佳做法中所述,使用LRUCache類緩存位圖。我也搜索了一個適合我的問題的解決方案。仍然無法解決這個問題。我自己處理縱向/橫向更改(將onConfigurationChanged()方法重寫)。將drawable-xhdpi中的所有圖片都放在一塊。當改變方向時,堆的大小與以前一樣增長,但仍在增長。任何幫助,將不勝感激......

例外:

02-13 22:44:09.419: E/dalvikvm-heap(935): 11448-byte external allocation too large for this process. 
02-13 22:44:09.419: E/dalvikvm(935): Out of memory: Heap Size=16391KB, Allocated=13895KB, Bitmap Size=16394KB, Limit=32768KB 
02-13 22:44:09.419: E/dalvikvm(935): Trim info: Footprint=16391KB, Allowed Footprint=16391KB, Trimmed=432KB 
02-13 22:44:09.419: E/GraphicsJNI(935): VM won't let us allocate 11448 bytes 

回答

0

OK第一次當surfaceCreated被稱爲在我的surfaceView類中,我調用這個方法,並且這個方法只被調用一次,而不是每次我在屏幕上顯示surfaceView時:

bitmapKeyboard = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyboard); 

bitmapGlowImages[0] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keycdown); 
bitmapGlowImages[1] = BitmapFactory.decodeResource(context.getResources(), R.drawable.blackkeydown); 
bitmapGlowImages[2] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyddown); 
bitmapGlowImages[3] = BitmapFactory.decodeResource(context.getResources(), R.drawable.blackkeydown); 
bitmapGlowImages[4] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyedown); 
bitmapGlowImages[5] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keycdown); 
bitmapGlowImages[6] = BitmapFactory.decodeResource(context.getResources(), R.drawable.blackkeydown); 
bitmapGlowImages[7] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyddown); 
bitmapGlowImages[8] = BitmapFactory.decodeResource(context.getResources(), R.drawable.blackkeydown); 
bitmapGlowImages[9] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyddown); 
bitmapGlowImages[10] = BitmapFactory.decodeResource(context.getResources(), R.drawable.blackkeydown); 
bitmapGlowImages[11] = BitmapFactory.decodeResource(context.getResources(), R.drawable.keyedown); 

在這個類中還運行一個單獨的線程來繪製按鍵:與canvas.drawBitmap(bitmap, null, destRect, null)。最後,當調用onDestroy時,我的方法recycleBitmaps()被稱爲

public void recycleBitmaps() { 
     if(bitmapKeyboard != null) { 
      bitmapKeyboard.recycle(); 
      bitmapKeyboard = null; 
      for(int i = 0; i < bitmapGlowImages.length; i++) { 
       bitmapGlowImages[i].recycle(); 
       bitmapGlowImages[i] = null; 
      } 
      System.gc(); 
     } 
} 

就是這樣。每次在風景中,我添加我的景觀佈局和我的父視圖我的surfaceView和肖像我再次刪除它,並加載我的肖像佈局。我在中這樣做,因爲我自己處理方向更改,所以每次更改設備方向時都不會銷燬和創建應用程序。

+0

好吧,它現在可能不會崩潰應用程序。我旋轉了大約20-30次。在6-7輪後,它仍然在堆上分配更多的存儲空間(但現在只有300-400kb)。當堆大小達到時,它會崩潰,現在它只會增加堆大小。我將所有可繪製文件夾(mdpi,ldpi,xhdpi,hdpi)中的png文件複製過來。但問題仍然存在...我認爲它涉及到圖片縮放ldpi,hdpi等。 – sNore 2013-02-14 16:03:21