Voy a retomar después de meses el blog, a ver si consigo documentar cada problema que me encuentro mientras programo con Android.

Hoy me he topado con un problema típico cuando programas con GUI gráfica, y es que muchas veces necesitamos actualizar o interactuar con la interfaz gráfica desde un thread que no es el principal, en jerga de Android: cuando queremos modificar el GUI de una Actividad desde otro thread. Concretamente en este caso, necesito que una tarea periódica (thread) muestre un pop-up en la interfaz (actividad) informando que está buscando señal GPS.

Lo primero es saber como ejecutar un método periódicamente en Android. Para ello podemos utilizar la clase nativa de Java llamada TimerTask. Podemos configurar el delay (de la primera ejecución) y el periodo(de la siguientes ejecuciones). Si desde el método run de esta TimerTask intentamos modificar cualquier cosa relacionado con la interfaz gráfica que se ejecuta en el thread principal, veremos como la aplicación se queda congelada, o simplemente muestra un error indicando que sólo se puede acceder a la interfaz desde el thread principal (actividad).

A continuación os dejo el código de cómo configurar y crear una TimerTask (intentad obviar la línea en negrita, que posteriormente explicaremos):

private void launchTask()
{
  int delay = 1000; // delay for 1 seconds
  int period = 120000; // repeat every 2minutes

  mTimer = new Timer();
  mTimer.scheduleAtFixedRate(new TimerTask() {
    public void run() {
      handler_ProgressDiaglog.sendEmptyMessage(0);
    }
  }, delay, period);
}

La línea que aparece en negrita en el cuerpo del método run, es la clave para la solución de nuestro problema. Básicamente lo que implementa por debajo es un paso de mensajes entre threads y que Java nos lo abstrae con la clase Handler(). Para que a nuestro thread principal (que tiene acceso al GUI) le llegue el mensaje que genera la TimerTask, tenemos que crear un atributo privado de tipo Handler. A continuación os dejo el código del Handler:

private Handler handler_ProgressDiaglog = new Handler() {
  @Override
  public void handleMessage(Message msg) {

    // We can modify the GUI here.

  }
};

NOTA: Es posible que un mismo handler recoga más de 1 mensaje, por lo que no es necesario crear un handler por mensaje que queramos transmitir. En nuestro caso, no nos interesa un mensaje en concreto, nada más que nos avise cuando la TimerTask ejecute.

Espero que os siva de ayuda esta recetilla de cómo solucionar en Android un problema típico que se da cuando queremos acceder al GUI desde un thread, que no es el principal.

facebooktwittergoogle_pluslinkedinmailby feather
Categories: androidcodigo

2 Comments

Jesús · March 31, 2011 at 3:42 am

Hola amigo. Muchas gracias por la información. Yo tengo un problema que resolver y creo que la solución está relacionada con tu comentario.
Tengo instalados unos sensores de temperatura que cada vez que detectan una variación concreta, informan de ello.

Por una parte, tengo un proyecto Java con todos los métodos implementados y que me informan correctamente cada vez que hay alguna variación. En el método genérico hay un bucle infinito que se mantiene a la espera de recibir comandos de los sensores.
En estos momentos estoy desarrollando una aplicación en Android para mostrar las variaciones en tiempo real de dichos sensores. La cuestión es que al pulsar el button para ejecutar dicha acción se llama al método de mi aplicación java y la aplicación se queda bloqueada. Debe ser porque indirectamente ejecuto un método que tiene un bucle infinito. ¿Crees que es porque debería pasar la ejecución de este método a segundo plano? ¿Me podrías dar alguna idea? Muchas gracias. Un saludo

rocapal · April 25, 2011 at 6:04 am

Buenas Jesús, si la aplicación se te queda bloqueada cuando das al botón, es porque ese código del botón se queda bloqueado o no termina nunca (bucle infinito). Para evitarlo, utiliza un AsyncTask para ejecutar el código del botón, mira la doc de Android para el AsyncTask, que te ayudará mucho.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts

android

Video Surveillance HD: Raspberrypi + PiCam + Android

The video-surveillance field is active many years ago, but there is only products that show image and little else. It’s need to add intelligence to surveillance tasks. We are committed to create technology to care for people and avoid dangerous situations. For this Read more…

android

Show your RTSP video in Android with VLC

If you have developed an Android app with video streaming, I’m sure you notice that Android use a pre-load of video buffer that fills in 10 seconds. This delay is hardcode in the source code. Read more…

android

Android SDK 64bit and Debian amd64

As you know, it’s possible download the Android SDK for 32 and 64 bits architecture.  If you choose 64bit architecture you notice that some binaries are compiled to 32bit architecture 1 2 3 vega:$/android/sdk/platform-tools$ file Read more…