Comment exécuter une tâche async pour chaque X minutes dans android?
comment exécuter la tâche async à un moment précis? (Je veux l'exécuter toutes les 2 minutes)
j'ai essayé d'utiliser post delayed mais ça ne marche pas?
tvData.postDelayed(new Runnable(){
@Override
public void run() {
readWebpage();
}}, 100);
dans le code readwebpage ci-dessus est la fonction qui appelle la tâche async pour moi..
dès maintenant 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 j'ai mon code et il fonctionne parfaitement bien mais le gros problème que j'draine la batterie?
9 réponses
vous pouvez utiliser handler si vous voulez initier 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 tir 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 prendre un certain temps (comme télécharger ou transférer sur le web), alors vous devez utiliser ScheduledExecutorService
scheduleWithFixedDelay
fonction à la place.
Utiliser 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)
Vous pouvez utiliser TimerTask au lieu d'AsyncTask.
ex:
Timer myTimer = new Timer("MyTimer", true);
myTimer.scheduleAtFixedRate(new MyTask(), ASAP, TWO_MINUTES);
private class MyTask extends TimerTask {
public void run(){
readWebPage();
}
}
quand le téléphone passe en mode veille, pour sauver la batterie, et il est tout à fait possible de se produire dans les 2 minutes, Handler.postDelayed()
peut manquer l'heure prévue. Pour ces activités, vous devez utiliser AlarmManager
, obtenir un verrouillage avec PowerManager
pour éviter d'aller dormir en arrière pendant que vous courez L'AsyncTask.
Voir mon message avec le code exemple ici
vous pouvez aussi lire Planification De La Répétition Des Alarmes
essayez d'étendre le Thread
classe, définissez un temps de sommeil de 2000 millis et le lieu de votre appel dans le run
méthode. Cela devrait le faire.
Vous pouvez utiliser le temps avec Handler et TimeTask
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 la balise' check'
je suggère d'aller avec Handler#postDelayed(Runnable)
. Gardez à l'esprit que cette méthode ne fonctionnera que lorsque votre application fonctionne (peut être en arrière - plan) mais si l'utilisateur le ferme manuellement ou si Android n'a plus de mémoire, il cessera de fonctionner et ne sera pas redémarré plus tard-pour que vous ayez besoin d'utiliser les 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 va attendre 2 minutes, exécuter votre code, et puis continuer à le faire toutes les 2 minutes. Mais si vous voulez qu'il fonctionne instantanément pour la première fois - et démarrer l'attente en boucle, au lieu d'utilisation:
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 que juste une méthode (readWebsite()
dans ce cas), et vous ne voulez pas que d'être 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 exactement comme le premier exemple mais a un délai de 0ms avant la première course 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)
Exécuter plusieurs messages(Runnables) puis il faut utiliser la fonction Looper classe qui est responsable de la création d'une file d'attente dans le fil. Par exemple, en écrivant une application qui télécharge des fichiers à partir d'internet, nous pouvons utiliser Looper class pour mettre des fichiers à télécharger dans la file d'attente. Cela vous aidera à effectuer la tâche async dans 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);
vous pouvez lancer une boucle à l'intérieur de la AsyncTask
qui dort pendant deux secondes entre les tâches. Quelque chose comme ceci:
protected Result doInBackground (Params... params) {
while (!interrupted) {
doWork();
Thread.sleep(2000);
}
}