2011-12-06 2 views
9

Sto usando il seguente codice per rimuove bambino su ogni viewgroup:Android: impossibile distruggere l'attività

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(); 
    } 
} 

dove la vista: R.id.RelativeLayout1 è un ListView.

Ma fare questo devo en eccezione:

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

Come posso risolvere questo problema?

risposta

11

Bene, il registro degli errori praticamente lo spiega: non chiamare removeAllViews() su AdapterView. E il tuo codice ad un certo punto incontra ViewGroup che è anche AdapterView.

Basta escludere questo caso utilizzando instanceof oppure gestire l'eccezione con il wrapper try/catch.

+1

Qualche idea sul perché AddapterView non supporta questa operazione? Non ho trovato nulla in riferimento ufficiale di AdapterView su di esso. – r1k0

+0

@ r1k0, Sì, perché AdapterView gestisce i suoi figli internamente. Non è possibile aggiungerli/rimuoverli in quanto ciò potrebbe rompere il suo stato interno. – inazaruk

0

Rimuovere quella linea? O almeno controllare se l'operazione è supportata con try e catch.

Inoltre, è un po 'di confusione voler fare questo in un metodo chiamato unbindDrawables, a meno che non sia solo un metodo con un nome errato (non descrive ciò che fa completamente).

Stai chiamando tutto questo in onDestroy? Se è così, c'è il vantaggio di farlo? Avevo l'impressione che il sistema si occupasse di questo genere di cose per te.

+0

OnDestroy chiamano "unbindDrawables (..)" "liberarMemoria()" e questa chiamata. Devo farlo manualmente per garantire la distruzione di Bitmap. –

+0

Giusto ... ma 'removeAllViews' non è necessario ed è sicuro rimuoverlo qui – Craigy

0

Non chiamarlo. UnsupportedOperationException ti dice che questo metodo non è supportato o funzionale quindi dovrai eseguire l'operazione in un altro modo. Non vedo la necessità di chiamare questo comunque come il garbage collector gestirà questa attività. Il riciclo delle bitmap dovrebbe essere fatto manualmente se è necessario assicurarne il completamento.

+0

Voglio riciclare Bitmap e devo farlo manualmente, ma qual è il modo migliore? –

+0

Non posso dire il modo migliore senza vedere tutto il tuo sorgente ma dovresti farlo in 'onDestroy()' e tenere traccia di tutti gli oggetti 'Bitmap' usati così puoi' recycle() 'loro. –

7

Verificare se ViewGroup non è un'istanza di AdapterView.

fare qualcosa di simile:

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

Quindi, il tuo codice:

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(); 
}