web-dev-qa-db-fra.com

Android - Contrôler une tâche avec Timer et TimerTask?

J'essaie actuellement de configurer une analyse WiFi dans mon Android qui recherche les points d'accès WiFi toutes les 30 secondes.

J'ai utilisé Timer et TimerTask pour que le scan fonctionne correctement aux intervalles dont j'ai besoin.

Cependant, je veux pouvoir arrêter et démarrer la numérisation lorsque l'utilisateur appuie sur un bouton et j'ai actuellement des problèmes pour arrêter puis redémarrer le Timer et la TimerTask.

Voici mon code

TimerTask scanTask;
final Handler handler = new Handler();
Timer t = new Timer();

public void doWifiScan(){

scanTask = new TimerTask() {
        public void run() {
                handler.post(new Runnable() {
                        public void run() {
                         wifiManager.scan(context); 
                         Log.d("TIMER", "Timer set off");
                        }
               });
        }};


    t.schedule(scanTask, 300, 30000); 

 }

  public void stopScan(){

   if(scanTask!=null){
      Log.d("TIMER", "timer canceled");
      scanTask.cancel();
 }

}

Ainsi, le minuteur et la tâche démarrent correctement et l'analyse se produit toutes les 30 secondes, mais je n'arrive pas à l'arrêter, je peux arrêter le minuteur, mais la tâche se produit toujours et scanTask.cancel () ne semble pas fonctionner non plus.

Y a-t-il une meilleure manière de faire cela? Ou est-ce que je manque quelque chose dans les classes Timer/TimerTask?

37
Donal Rafferty

Vous pourriez envisager:

  • Examen du résultat booléen de l'appel de cancel() sur votre tâche, car il devrait indiquer si votre demande réussit ou échoue
  • Essayez purge() ou cancel() sur le Timer au lieu du TimerTask

Si vous n'avez pas nécessairement besoin de Timer et TimerTask, vous pouvez toujours utiliser postDelayed() (disponible sur Handler et sur tout View). Cela programmera un Runnable à exécuter sur le thread d'interface utilisateur après un délai. Pour qu'il se reproduise, il suffit de le programmer à nouveau après avoir effectué votre travail périodique. Vous pouvez ensuite surveiller un indicateur booléen pour indiquer quand ce processus doit se terminer. Par exemple:

private Runnable onEverySecond=new Runnable() {
    public void run() {
        // do real work here

        if (!isPaused) {
            someLikelyWidget.postDelayed(onEverySecond, 1000);
        }
    }
};
27
CommonsWare

en utilisant votre code, au lieu de

scanTask.cancel();

la bonne façon est d'annuler votre minuterie (pas timerTask):

t.cancel();
6
tony gil

La documentation Android indique que cancel () annule le minuteur et toutes les tâches planifiées. S'il y a une tâche en cours d'exécution, elle n'est pas affectée. Plus aucune tâche ne peut être planifiée sur ce minuteur. Les appels suivants le font rien, ce qui explique le problème.

5
Mike