jueves, 16 de octubre de 2014

Tareas en 2º plano Android (Parte II): Clase TimerTask

Buenas amigos, en el tema anterior estuvimos hablando de como realizar una tarea en segundo plano con la ayuda de la clase AsyncTask. En este nuevo tema vamos a ver como funciona la clase TimerTask y sus diferencias con AsyncTask y nos va a resultar menos compleja de entender ya que nos va a resultar más familiar que AsyncTask.



Bien, esta clase se caracteriza por hacer repeticiones del hilo continuamente cada X segundos, es decir, funciona como un temporizador pudiendole indicar cuando queremos que inicie y cada cuanto tiempo queremos que se repita, estas repeticiones van a ser infinitas, es decir, una vez ejecutemos el hilo no parará de ejecutarse hasta que nosotros se lo indiquemos

Anteriormente, en java, para hacer esto con los threads, creabamos un bucle infinito (while, for...) y por medio del método sleep() le indicabamos cada cuanto tiempo haciamos una repetición, bien, TimerTask funciona más o menos de la misma forma pero por si sola, no hace falta poner sleep() ni nada parecido.

Bien, sabiendo esto, una clase TimerTask se construye de la misma forma que una AsyncTask, es decir, como una clase interna:


Podemos observar, que efectivamente se construye como una clase interna de TimerExample y, a diferencia de AsyncTask, no utilizamos ni genéricos, ni métodos especiales que se ejecuten antes y/o después de realizar nuestra acción en segundo plano, aquí solo tenemos un método run() en el que poner nuestro código a ejecutar en segundo plano.

Una vez creada nuestra clase interna TimerTask, vamos a hacer que funcione, para ello vamos a utilizar la clase Timer.

NOTA: Una cosa antes de continuar, en lineas anteriores mencionabamos que TimerTask se encargaba de hacer repeticiones cada X segundos y que se iniciaba cuando nosotros se lo indicábamos, pues bueno, eso no es del todo cierto, quien realmente realiza esa función es la clase Timer, que vamos a ver ahora, TimerTask solo es el recipiente de nuestro código en segundo plano, pero realmente es Timer quien lo ejecuta. Recordarlo bien, ya que en lineas anteriores no os quería confundir y por eso hago esta aclaración ahora.

Bien, aclarado lo anterior, vamos a instanciar un objeto de la clase Timer y pasarle nuestro AsyncTask para ejecutar el hilo:


  • Creamos un atributo de la clase Timer:
       private Timer timer;

  •  En nuestro método onCreate() lo instanciamos:
                 timer=new Timer();
  • Creamos un objeto de nuestra clase AsyncTask:
               SubTimerExample sub=new SubTimerExample();
  • Ahora le pasamos al método scheduleAtFixedRate() de timer el TimerTask a ejecutar (sub), cuando lo queremos ejecutar (0) y cada cuanto tiempo se va a repetir en milisegundos (5000):
              timer.scheduleAtFixedRate(sub, 0, 5000);

Y ya está, con esto tenemos nuestro timer ejecutando a nuestro TimerTask cada X segundos, en caso de querer cancelar nuestra tarea en segundo plano utilizaremos los siguientes métodos de la clase Timer, OJO, es la clase Timer la que cancela el hilo, no la TimerTask:

  • void cancel(): Cancela nuestro timer:
              timer.cancel();
  • int purgue(): Remueve todos los timers cancelados de la pila de memoria. Importantisimo para controlar el consumo de memoria de nuestra app.
              timer.purge(); 

Estos 2 métodos junto con el método scheduleAtFixedRate(), son los más utilizados por esta clase.

Bien chicos, como podeis observar, estas clases son tan iguales como distintas, las Asynctask por un lado te permiten hacer más acciones mientras se ejecuta la tarea en segundo plano y nos viene bien para hacer Dialogs, ProgressDialogs y cosas así, mientras que Timer nos viene bien por si queremos actualizar nuestra activity cada X segundos, o hacer alguna comprobación de servidor cada X segundos, aunque para esto último es mejor usar los servicios, que explicaré pronto, aún así, sois vosotros los que finalmente decidiréis cual de las dos se adapta más a vuestra situación.

Bien amigos, eso es todo, si tenéis alguna duda u os atascais en algo, preguntar.

Un saludo.





7 comentarios:

  1. Gracias!!.. Funciona perfectamente!

    ResponderEliminar
  2. tengo una duda, como hago que ka velocidad vaya incrementando cada cierto tiempo?

    ResponderEliminar
  3. Buenas tardes quisiera saber si puedo hacer consultas a un webservice atraves de timertask..

    ResponderEliminar
  4. Buenisimo, no era lo que andaba buscando pero me servirá para próximos proyectos, los conocimientos no caen mal.

    ResponderEliminar
  5. Hola amigos, la explicación perfecta!!!
    Estoy comenzando con andorid y JAVA, tengo este problema: dentro del método run intento hacer un Toast y no puedo.Por favor cómo puedo resolverlo? Gracias

    ResponderEliminar
    Respuestas
    1. Buenas, tienes que ejecutarlo dentro de otro Thread, prueba poniendo dentro del run lo siguiente:

      runUiThread(new runnable() {
      public void run() {
      //tu toast
      }
      }). start() ;

      Eliminar