sábado, 12 de abril de 2014

Android - Planificador de tareas (scheduler)

Para crear una aplicación que se ejecute cada cierto tiempo en Android podemos hacerlo de dos modos diferentes, mediante el uso de timers o mediante el uso de  la clase ScheduledThreadPoolExecutor. En este artículo vamos a usar la clase ScheduledThreadPoolExecutor.

La clase ScheduledThreadPoolExecutor se trata de una implementación de un pool de hilos de ejecución de java.

Para instanciar una un pool de hilos con un número n de hilos podemos usar la clase java.util.concurrent.Executors, que mediante la función newScheduledThreadPool(n) nos retornará un pool con el número de hilos requeridos. Para nuestro ejemplo vamos a pedir un único hilo:

private ScheduledThreadPoolExecutor sch = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);

Otra clase que es importante y que vamos a usar es ScheduledFuture. Esta clase nos permite controlar la acción a ejecutar de modo que en cualquier momento podamos cancelar el scheduler.

        // Definir que una tarea (una instancia del tipo Runnable) se ejecute cada 10 segundos.
        periodicFuture = sch.scheduleAtFixedRate(tarea, 0, 10,  TimeUnit.SECONDS);

Para cancelar la tarea sólo es necesario usar la función cancel de la clase ScheduledFuture.

       periodicFuture.cancel(false);

A continuación  veamos todo el código junto de modo tenemos una clase que cada 10 segundos ejecutará un System.out


package com.ljlg.blogscheduler;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class MySchedule {
    private ScheduledThreadPoolExecutor sch = (ScheduledThreadPoolExecutor) Executors
            .newScheduledThreadPool(1);

    private ScheduledFuture<?> periodicFuture;
  
    public void start() {
        // Tarea que queremos ejecutar
        Runnable tarea = new Runnable() {
            @Override
            public void run() {
                // Tú código aquí
                System.out.println("Probando");
            }
        };

        // Indicar cuando se ejecuta la próxima ejección
        periodicFuture = sch.scheduleAtFixedRate(tarea, 0, 10,
                TimeUnit.SECONDS);
    }

    public void stop() {
        periodicFuture.cancel(false);
    }
}


Finalmente sólo será necesario que instanciemos nuestra clase desde nuestro programa. Por ejemplo si tenemos un programa con un botón de comenzar y otro de parar tendríamos algo como lo siguiente:



public class MainActivity extends ActionBarActivity {
   
    private Button btnStart;
   
    private Button btnStop;
   
    MySchedule sd = new MySchedule();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnStart = (Button) findViewById(R.id.button1);
       
        btnStart.setOnClickListener(new OnClickListener() {
              
            // Acción a ejecutar cada vez que se pulse el botón
            @Override
            public void onClick(View v) {
                sd.start();           
            }
        });    
       
        btnStop = (Button)findViewById(R.id.button2);
        btnStop.setOnClickListener(new OnClickListener() {
              
            // Acción a ejecutar cada vez que se pulse el botón
            @Override
            public void onClick(View v) {
                sd.stop();           
            }
        });    
       
    }
 .........
}



No hay comentarios:

Publicar un comentario