web-dev-qa-db-fra.com

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

comment exécuter la tâche asynchrone à une heure précise? (Je veux le lancer toutes les 2 minutes)

J'ai essayé d'utiliser post différé mais ça ne marche pas?

    tvData.postDelayed(new Runnable(){

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

    }}, 100);

Readwebpage est une fonction qui appelle la tâche asynchrone pour moi.

En ce moment ci-dessous est 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 que je décharge ma batterie?

40
Shan

Vous pouvez utiliser handler si vous voulez lancer quelque chose toutes les X secondes. Handler est bon parce que vous n'avez pas besoin de fil supplémentaire pour garder 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 la position de mise à jour de la lecture audio dans l'interface utilisateur). Si cela peut éventuellement prendre un certain temps (comme le téléchargement ou le téléchargement sur le Web), utilisez plutôt la fonction ScheduledExecutorService 's's scheduleWithFixedDelay.

64
inazaruk

Utilisez Handler et 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)
29
Elenasys

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

}
7
Berkay

Lorsque le téléphone passe en mode veille, pour économiser la batterie, et qu'il est tout à fait possible que cela se produise dans un intervalle de 2 minutes, Handler.postDelayed() peut manquer l'heure programmée. Pour de telles activités, vous devez utiliser AlarmManager, verrouillez-vous avec PowerManager pour éviter de vous rendormir pendant l'exécution de la tâche Async.

Voir mon post avec exemple de code ici

Vous voudrez peut-être aussi lire Planification des alarmes répétitives

1
Mixaz

Je suggère d'aller avec Handler#postDelayed(Runnable). Gardez à l'esprit que cette méthode ne fonctionnera que lorsque votre application sera en cours d'exécution (peut être en arrière-plan), mais si l'utilisateur la ferme manuellement ou si Android manque de mémoire, il ne fonctionnera plus et ne sera pas redémarré plus tard - 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écutez votre code, puis continuez à le faire toutes les 2 minutes. Mais si vous voulez qu'il fonctionne instantanément pour la première fois - et alors lance la boucle wait-do, utilisez plutôt:

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 que 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 identique au premier exemple mais a un délai de 0 ms 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 modification. J'ai donc dû en ajouter une nouvelle.)

1
Nicofisi

Essayez d'étendre la classe Thread, définissez une durée de sommeil de 2 000 millis et placez votre appel dans la méthode run. Ça devrait le faire.

0
Egor

Vous pouvez utiliser Time avec Handler et TimerTask

  final Handler handler = new Handler();
        Timer timer = new Timer();
        TimerTask backtask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                        try {
                            //To task in this. Can do network operation Also
                            Log.d("check","Check Run" );
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                        }
                    }
                });
            }
        };
        timer.schedule(backtask , 0, 20000); //execute in every 20000 ms*/

Vous pouvez vérifier logcat pour vérifier si vous utilisez ou non le nom de balise 'check'

0
Ishan Fernando

Exécutez plusieurs messages (Runnables) puis utilisez la classe Looper qui est responsable de la création d’une file d’attente dans le thread. Par exemple, lorsque vous écrivez une application qui télécharge des fichiers sur Internet, vous pouvez utiliser la classe Looper pour placer les fichiers à télécharger dans la file d'attente. Cela vous aidera à effectuer des tâches asynchrones sous Android ...

HandlerThread hThread = new HandlerThread("HandlerThread");
  hThread.start();
  Handler handler = new Handler(hThread.getLooper());
  final Handler handler1 = new Handler(hThread.getLooper());
  final long oneMinuteMs = 60 * 1000;

  Runnable eachMinute = new Runnable() { 
   @Override
   public void run() {
    Log.d(TAG, "Each minute task executing");
    handler1.postDelayed(this, oneMinuteMs);
    sendPostRequest();
   }
  };
 // sendPostRequest();
  // Schedule the first execution
  handler1.postDelayed(eachMinute, oneMinuteMs);
0