2011-12-06 18 views
9

Estoy utilizando el código siguiente para quita del niño en cada ViewGroup:Android: No se puede destruir la actividad

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

donde la vista: R.id.RelativeLayout1 es un ListView.

Pero hacer esto tengo es una excepción:

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

¿Cómo puedo solucionar esto?

Respuesta

11

Bueno, el registro de errores lo explica bastante bien: no llame al removeAllViews() en AdapterView. Y su código en algún momento cumple con ViewGroup que también es AdapterView.

Simplemente descarte este caso usando instanceof controle o maneje la excepción con try/catch envoltura.

+1

¿Alguna idea de por qué AddapterView no es compatible con esta operación? No pude encontrar nada en la referencia oficial de AdapterView al respecto. – r1k0

+0

@ r1k0, Sí, eso es porque AdapterView administra internamente a sus hijos. No puede agregarlos/eliminarlos ya que esto podría romper su estado interno. – inazaruk

0

Eliminar esa línea? O al menos verificar si la operación es compatible con try y catch.

Además, es un poco confuso a querer hacer esto en absoluto en un método llamado unbindDrawables, a menos que sea sólo un método mal llamada (no describe lo que hace totalmente).

¿Estás llamando todo esto en onDestroy? Si es así, ¿hay algún beneficio de hacer esto? Tenía la impresión de que el sistema se encarga de este tipo de cosas para usted.

+0

OnDestroy llaman "unbindDrawables (..)", "liberarMemoria()" y esta llamada. Debo hacerlo manualmente para asegurar la destrucción de Bitmap. –

+0

Derecha ... pero 'removeAllViews' no es necesario y es seguro eliminarlo aquí – Craigy

0

no lo llaman. UnsupportedOperationException le indica que este método no es compatible o no es funcional, por lo que tendrá que realizar la tarea de otra manera. No veo la necesidad de llamar esto de todos modos ya que el recolector de basura se encargará de esta tarea. El reciclaje de mapas de bits debe hacerse manualmente si necesita asegurarse de que se realice.

+0

Quiero reciclar Bitmap y debo hacerlo manualmente, pero ¿cuál es la mejor manera? –

+0

No puedo decirte la mejor manera sin ver toda tu fuente, pero deberías hacerlo en 'onDestroy()' y hacer un seguimiento de todos los objetos 'Bitmap' usados ​​para que puedas' reciclarlos() '. –

7

Compruebe si su ViewGroup no es una instancia de AdapterView.

hacer algo así:

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

Así, en su código:

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