jueves, 9 de mayo de 2013

CalledFromWrongThreadException


Uno de los requisitos clásicos de Android es que cualquier modificación sobre una vista debe ser realizada desde el hilo que la creó (generalmente referido como el UI Thread). Esto hace que no sea raro que cuando empecemos a trabajar con hilos acabemos encontrándonos con la excepción:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Ante esta excepción lo primero que tenemos que preguntarnos es si realmente queremos modificar la vista desde donde lo estamos haciendo. Si la respuesta es afirmativa, podemos recurrir al método runOnUiThread de la clase Activity. Un posible ejemplo de uso sería el siguiente.

Tenemos una actividad de una aplicación que permite conexiones por bluetooth. En pantalla se muestra un botón, y cuando lo pulsamos, ponemos en marcha un servidor, que se mantiene a la espera de conexiones. Este trabajo se realiza en un hilo independiente que es lanzado desde nuestra actividad. Lo que queremos conseguir es mostrar un texto informando de que el servidor está esperando conexiones, y ocultarlo cuando éste se detenga.

Damos a nuestro hilo una referencia a la actividad, y en ésta añadimos un método para mostrar u ocultar el texto informativo. Al final del método run() del hilo añadimos una llamada a ese nuevo método.

public class XXX extends Thread {
....

public void run() {
...
activity.setTextVisible(false);
}
...
}

public class XXX extends Activity {
...
public void setTextVisible(boolean visible) {
text.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
}

Excepción asegurada.

Pero si cambiamos la implementación del método setTextVisible a:

public void setTextVisible(boolean visible) {
runOnUiThread(new Runnable() {
public void run(){
text.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
}
});
}

Todo marchará como la seda.

No hay comentarios:

Publicar un comentario

Cualquier aportación será bienvenida