2010-07-12 17 views
7

Necesito ejecutar una tarea periódica en una aplicación de Android. Actualmente uso de un temporizador como esto:El cambio del reloj del sistema Android detiene los temporizadores. ¿Cómo puedo reiniciarlos?

final Handler guiHandler = new Handler(); 

// the task to run 
final Runnable myRunnable = new Runnable() { 

    @Override 
    public void run() { 
     doMyStuff(); 
    } 
}; 

Timer timer = new Timer(); 
timer.schedule(new TimerTask() { 

    @Override 
    public void run() { 
     guiHandler.post(myRunnable); 
    } 
}, 0, 30000); // run every 30 seconds 

Esto hace exactamente lo que necesito, pero hay un problema: si cambio de la hora en el emulador o en el teléfono, el temporizador deja de funcionar. Esto es lo que aparece en el registro cuando cambio el tiempo:

D/SystemClock( 331): Setting time of day to sec=1278920137 
W/SystemClock( 331): Unable to set rtc to 1278920137: Invalid argument 

Nada sobre el temporizador se interrumpe, pero está claro que no se ejecuta más después de que el reloj del sistema ha cambiado. Necesito la tarea de seguir corriendo todo el tiempo mientras se ejecuta la aplicación.

¿Cómo puedo reiniciar el temporizador si se queda parado como este? No hay ningún método en el Timer o TimerTask para comprobar si se está ejecutando actualmente, por lo que no puedo saber cuándo reprogramarlo. ¿Algunas ideas?

Respuesta

3

Creo que hay algunas formas de hacerlo. No usaría el temporizador en ningún caso.

Se puede utilizar un controlador para ejecutar su tarea en una llamada postDelayed. Su tarea tendría que volver a registrarse con el controlador desde sí mismo.

final int ONE_SECOND = 1000; // one second 
final Handler handler = new Handler(); 
handler.postDelayed(new Runnable() { 
    public void run() { 
     ... // do some stuff 
     if (expression) { 
     handler.postDelayed(this, ONE_SECOND); 
     } 
    } 
}, ONE_SECOND); 

Esto mantendrá la tarea ejecutándose mientras la aplicación está activa. También puede ajustar la tasa de retraso en el postDelay dentro de Runnable. De esta manera es semi predecible siempre y cuando hagas otro Looper. Usar el hilo principal puede o no ser apropiado según la tarea.

También hay un AlarmManager, que se puede acceder a través de la interfaz de contexto, que está destinado para tareas repetitivas tareas a intervalos más precisos. Es un poco más complejo de usar pero se obtiene la flexibilidad de usar el RTC y persistir tareas repetibles.

AlarmManager manager = mContext.getSystemService(Context.ALARM_SERVICE); 
manager.setRepeating(AlarmManager.RTC, 
    <start_time_millis>, 
    <period_millis>, 
    pendingIntent); 

Por ejemplo, la intención en espera puede disparar un intento de difusión que se puede escuchar a otros lugares. Puede crear este pendiente en el onCreate de su objeto de aplicación personalizado y cancelar el intento en el onTerminate().

+0

¡esta es la gran solución que estoy buscando! Gracias – JosephT

Cuestiones relacionadas