2011-12-06 65 views
9

我使用下面的代碼在每一個ViewGroup中去除孩子的:安卓:無法銷燬活動

protected void onDestroy() { 
    super.onDestroy(); 
    this.liberarMemoria(); 
} 

public void liberarMemoria(){ 
    imagenes.recycleBitmaps(); 
    this.unbindDrawables(findViewById(R.id.RelativeLayout1)); 
    System.gc(); 
} 
private void unbindDrawables(View view) { 
    if (view.getBackground() != null) { 
    view.getBackground().setCallback(null); 
} 
if (view instanceof ViewGroup) { 
    for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
     unbindDrawables(((ViewGroup) view).getChildAt(i)); 
    } 
    ((ViewGroup) view).removeAllViews(); 
    } 
} 

,其視圖:R.id.RelativeLayout1是一個ListView。

但這樣做我都設有例外:

E/AndroidRuntime(582): java.lang.RuntimeException: Unable to destroy activity {...}: java.lang.UnsupportedOperationException: removeAllViews() is not supported in AdapterView 

我該如何解決這個問題?

回答

11

那麼,錯誤日誌幾乎可以解釋它:不要致電removeAllViews()AdapterView。並且您的代碼在某些時候符合ViewGroup也是AdapterView

只需使用instanceof檢查或處理與try/catch包裝的異常來判斷此案例。

+1

任何想法爲什麼AddapterView不支持此操作?我無法在AdapterView的官方參考資料中找到任何關於它的內容。 – r1k0

+0

@ r1k0,是的,這是因爲AdapterView在內部管理其子級。您無法添加/刪除它們,因爲這可能會破壞其內部狀態。 – inazaruk

0

刪除該行?或者至少檢查trycatch是否支持該操作。

另外,想要在所謂的unbindDrawables方法中完成此操作有點令人困惑,除非它只是一個命名不正確的方法(並未完全描述它的作用)。

您是否打電話給onDestroy?如果是這樣,那麼從中獲益呢?我的印象是系統爲你處理這種事情。

+0

的onDestroy稱之爲 「liberarMemoria()」,這稱之爲 「unbindDrawables(..)」。我必須手動執行以確保Bitmap的銷燬。 –

+0

正確...但removeAllViews沒有必要,可以安全地在這裏刪除 – Craigy

0

不要調用它。 UnsupportedOperationException告訴你這個方法不被支持或者不可用,所以你必須以另一種方式來完成這個任務。無論如何,我不認爲需要這樣做,因爲垃圾收集器將處理此任務。如果需要確保完成位圖回收,應手動完成。

+0

我想回收位圖,我必須手動,但最好的方法是什麼? –

+0

我不能告訴你沒有看到所有源代碼的最佳方式,但是你應該在'onDestroy()'中執行它,並跟蹤所有使用的'Bitmap'對象,以便「回收()」它們。 –

7

驗證您的ViewGroup是否不是AdapterView的實例。

做這樣的事情:

if (!(view instanceof AdapterView<?>)) 
    ((ViewGroup) view).removeAllViews(); 

所以,在你的代碼:

if (view instanceof ViewGroup) { 
    for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
     unbindDrawables(((ViewGroup) view).getChildAt(i)); 
    } 
    if (!(view instanceof AdapterView<?>)) 
     ((ViewGroup) view).removeAllViews(); 
}