2010-11-25 91 views
0

我在我的應用程序中有3個圖像資源。 在ImageView中加載和顯示它們中的任何一個都可以順利進行。 但是,當我從佈局中刪除顯示的ImageView時,將其添加一個新圖像,然後 會變得奇怪。圖像處理過程崩潰(信號11)

要麼進程崩潰完全(信號11)當我嘗試對舊的位圖 調用.recycle()或我得到 情況下,我不使用回收OutOfMemoryError異常。

這隻發生在8以下的API級別,所以我的猜測是本地堆上的 GC錯誤導致它並且這些錯誤被固定在 2.2。然而,因爲2.1是目前最常見的版本,所以我需要一個解決方法...

同樣,本地堆應該不會缺少內存。我一次只持有 只有1張圖像,並且無效,所以GC應該能夠 檢索堆空間(就像2.2上發生的那樣)。

我創建了一個非常小的樣本應用程序,它可以從 這裏下載: http://www.4shared.com/file/QqHrhJLR/BitmapRecycleTest.html

任何建議將不勝感激。

回答

1

我看了一下。我在運行2.2.1的Nexus One上獲取信號11。這個callstack是這樣的:

I/DEBUG ( 56):   #00 pc 0000c584 /system/lib/libc.so 
I/DEBUG ( 56):   #01 pc 0000cd2e /system/lib/libc.so 
I/DEBUG ( 56):   #02 pc 0002c5dc /system/lib/libskia.so 
I/DEBUG ( 56):   #03 pc 00068108 /system/lib/libskia.so 
I/DEBUG ( 56):   #04 pc 00063a8c /system/lib/libskia.so 
I/DEBUG ( 56):   #05 pc 0004cefc /system/lib/libandroid_runtime.so 
I/DEBUG ( 56):   #06 pc 00016e34 /system/lib/libdvm.so 
I/DEBUG ( 56):   #07 pc 000452c4 /system/lib/libdvm.so 
I/DEBUG ( 56):   #08 pc 0001bd98 /system/lib/libdvm.so 
... 

很明顯這裏有一個bug,但它似乎是可以避免的。

不要使用你的BitmapResource類......你應該明確地回收()你的位圖時,你不再需要它們。我改變了你的DrawView構造函數:

public DrawView(Context context, int resId) { 
    super(context); 
    setImageResource(resId); 
} 

由於你的圖像太大 - 7MB解壓縮! - 在刪除上一張圖像後,我還添加了一個System.gc()buttonClickHandler現在看起來是這樣的:

public void buttonClickHandler(View v) { 
    Object tagObj = mSwitchButton.getTag(); 
    if (tagObj != null && tagObj instanceof ImageView) { 
     ImageView iv = (ImageView)tagObj; 
     iv.setImageBitmap(null); 
      mMainLayout.removeView(iv); 
     System.gc(); 
    } 

    addNewViewToLayout(mMainLayout); 
} 

有了這些改變你的應用程序運行對我罰款。

+0

我發佈的示例應用程序是「重現的最小代碼」,它來源於我遇到此問題的大得多的應用程序。 我需要BitmapResource,因爲在大型應用程序中,此類中有更多的邏輯。在它的終結器中的.recycle調用是因爲我有很多bmp被加載和卸載,所以我不能顯式地調用recycle(),因爲我會在所有地方回收調用。 但是,您建議的解決方案確實解決了我發佈的問題,並讓我考慮完全放棄回收呼叫,並在某些地方傳播System.gc()調用。 感謝您的幫助! – Roi 2010-11-25 16:53:36