47 votes

Comment exécuter une tâche asynchrone toutes les x minutes sous Android ?

Comment exécuter la tâche asynchrone à un moment précis ? (Je veux l'exécuter toutes les 2 minutes)

J'ai essayé d'utiliser le post delayed, mais ça ne marche pas ?

    tvData.postDelayed(new Runnable(){

    @Override
    public void run() {
        readWebpage();

    }}, 100);

Dans le code ci-dessus, readwebpage est une fonction qui appelle la tâche asynchrone pour moi

Actuellement, voici la méthode que j'utilise.

   public void onCreate(Bundle savedInstanceState) {

         readwebapage();

   }

   public void readWebpage() {
    DownloadWebPageTask task = new DownloadWebPageTask();
    task.execute("http://www.google.com");

   }

   private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        String response1 = "";
        response1=read(); 
                   //read is my another function which does the real work    
        response1=read(); 
        super.onPostExecute(response1);
        return response1;
    }

      protected void onPostExecute(String result) {

         try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            TextView tvData = (TextView) findViewById(R.id.TextView01);
            tvData.setText(result);

        DownloadWebPageTask task = new DownloadWebPageTask();
        task.execute(new String[] { "http://www.google.com" });

    }

    }

C'est ce que mon code est et il fonctionne parfaitement bien mais le gros problème est que je vide ma batterie ?

74voto

inazaruk Points 37760

Vous pouvez utiliser le handler si vous voulez déclencher quelque chose toutes les X secondes. Handler est une bonne solution car vous n'avez pas besoin d'un thread supplémentaire pour assurer le suivi lors du déclenchement de l'événement. Voici un court extrait :

private final static int INTERVAL = 1000 * 60 * 2; //2 minutes
Handler mHandler = new Handler();

Runnable mHandlerTask = new Runnable()
{
     @Override 
     public void run() {
          doSomething();
          mHandler.postDelayed(mHandlerTask, INTERVAL);
     }
};

void startRepeatingTask()
{
    mHandlerTask.run(); 
}

void stopRepeatingTask()
{
    mHandler.removeCallbacks(mHandlerTask);
}

Notez que doSomething ne devrait pas prendre longtemps (quelque chose comme mettre à jour la position de la lecture audio dans l'interface utilisateur). Si cela peut potentiellement prendre un certain temps (comme le téléchargement ou la mise en ligne sur le web), alors vous devriez utiliser ScheduledExecutorService 's scheduleWithFixedDelay à la place.

30voto

Elenasys Points 23268

Utilisez Handler y PostDelayed :

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    public void run() {
        readWebpage();
        handler.postDelayed(this, 120000); //now is every 2 minutes
    }
 }, 120000); //Every 120000 ms (2 minutes)

7voto

Berkay Points 662

Vous pouvez utiliser TimerTask au lieu de AsyncTask.

ex :

Timer myTimer = new Timer("MyTimer", true);
myTimer.scheduleAtFixedRate(new MyTask(), ASAP, TWO_MINUTES);

private class MyTask extends TimerTask {

    public void run(){
      readWebPage();
    }

}

2voto

Mixaz Points 104

Lorsque le téléphone passe en mode veille pour économiser la batterie, il est tout à fait possible que cela se produise dans un intervalle de 2 minutes, Handler.postDelayed() peuvent manquer l'heure prévue. Pour de telles activités, vous devez utiliser AlarmManager , obtenir un verrou avec PowerManager pour éviter de se mettre en veille pendant l'exécution de l'AsyncTask.

Voir mon post avec un exemple de code aquí

Vous pouvez également lire Programmation des alarmes répétitives

2voto

Nicofisi Points 101

Je suggère d'opter pour Handler#postDelayed(Runnable) . Gardez à l'esprit que cette méthode ne fonctionnera que lorsque votre application est en cours d'exécution (peut être en arrière-plan) mais si l'utilisateur le ferme manuellement ou si Android manque simplement de mémoire, il cessera de fonctionner et ne pourra pas être redémarré ultérieurement - pour cela, vous devez utiliser des services.

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
        /* your code here */
    }
}, 2 * 60 * 1000); // first run after 2 minutes

Ce code attendra 2 minutes, exécutera votre code, et continuera à le faire toutes les 2 minutes. Mais si vous voulez qu'il s'exécute instantanément pour la première fois - et puis lancer la boucle wait-do, utiliser à la place :

final Handler handler = new Handler();
 /* your code here */
new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
         /* and also here - your code */
    }
}.run(); 

ou, si votre code est plus long qu'une seule méthode ( readWebsite() dans ce cas), et vous ne voulez pas que cela soit dupliqué :

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
         /* your longer code here */
    }
}, 0); // first run instantly

(^ celui-ci est comme le premier exemple mais a un délai de 0ms avant la première exécution au lieu de 2 minutes)

(Cette réponse est basée sur celle de @Devashish Mamgain mais j'ai ajouté trop de détails pour une édition donc j'ai dû en ajouter une nouvelle)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X