2010-07-12 4 views
7

Je dois exécuter une tâche périodique dans une application Android. J'utilise actuellement une minuterie comme ceci:La modification de l'horloge système Android arrête les compteurs. Comment puis-je les redémarrer?

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 

Cela fait exactement ce que j'ai besoin, mais il y a un problème: si je change l'heure sur l'émulateur ou par téléphone, la minuterie cesse de fonctionner. C'est ce qui apparaît dans le journal quand je change le temps:

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

Rien au sujet de la minuterie étant interrompue, mais il ne fonctionne pas bien plus après l'horloge du système a changé. J'ai besoin de la tâche pour continuer à fonctionner tout le temps tant que l'application est en cours d'exécution. Comment puis-je redémarrer la minuterie si elle est arrêtée comme ça? Il n'y a aucune méthode sur le Timer ou le TimerTask pour vérifier s'il est en cours d'exécution, donc je ne peux pas savoir quand le replanifier. Des idées?

Répondre

3

Je pense qu'il y a plusieurs façons de le faire. Je n'utiliserais pas la minuterie dans les deux cas.

Vous pouvez utiliser un gestionnaire pour exécuter votre tâche dans un appel postDelayed. Votre tâche devrait alors se réinscrire auprès du gestionnaire de l'intérieur de lui-même.

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); 

Ceci permettra à la tâche de continuer à fonctionner pendant que votre application est active. Vous pouvez également ajuster le taux retardé dans le postDelayed dans Runnable. Cette façon de faire est semi-prévisible tant que vous faites un autre Looper. L'utilisation du thread principal peut être appropriée ou non selon la tâche. Il existe également un AlarmManager auquel vous pouvez accéder via l'interface Context, qui est destiné aux tâches récurrentes à des intervalles plus précis. C'est un peu plus complexe à utiliser mais vous avez la possibilité d'utiliser le RTC et les tâches répétables persistantes. Par exemple, l'intention en attente peut déclencher une intention de diffusion que vous pouvez écouter ailleurs. Par exemple, l'intention en attente peut déclencher une intention de diffusion. Vous pouvez créer ce pendingintent dans onCreate de votre objet Application personnalisé et annuler l'intention dans le onTerminate().

+0

c'est une excellente solution que je cherche! Merci – JosephT

Questions connexes