161 votes

Comment exécuter une méthode toutes les X secondes

Je développe une application Android 2.3.3 et j'ai besoin d'exécuter une méthode tous les jours. X secondes .

Dans iOS, j'ai NSTimer mais pour Android, je ne sais pas quoi utiliser.

Quelqu'un m'a recommandé Manipulateur ; un autre me recommande Gestionnaire d'alarme mais je ne sais pas quelle méthode convient le mieux aux NSTimer .

Voici le code que je souhaite mettre en œuvre dans Android :

timer2 = [
    NSTimer scheduledTimerWithTimeInterval:(1.0f/20.0f)
    target:self
    selector:@selector(loopTask)
    userInfo:nil
    repeats:YES
];

timer1 = [
    NSTimer scheduledTimerWithTimeInterval:(1.0f/4.0f)
    target:self
    selector:@selector(isFree)
    userInfo:nil
    repeats:YES
];

J'ai besoin de quelque chose qui fonctionne comme NSTimer .

Que me recommandez-vous ?

199voto

Jug6ernaut Points 2751

La solution que vous utiliserez dépend en fait du temps d'attente nécessaire entre chaque exécution de votre fonction.

Si vous attendez plus de 10 minutes, je vous conseille d'utiliser AlarmManager .

// Some time when you want to run
Date when = new Date(System.currentTimeMillis());

try {
    Intent someIntent = new Intent(someContext, MyReceiver.class); // intent to be launched

    // Note: this could be getActivity if you want to launch an activity
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
        context,
        0, // id (optional)
        someIntent, // intent to launch
        PendingIntent.FLAG_CANCEL_CURRENT // PendingIntent flag
    );

    AlarmManager alarms = (AlarmManager) context.getSystemService(
        Context.ALARM_SERVICE
    );

    alarms.setRepeating(
        AlarmManager.RTC_WAKEUP,
        when.getTime(),
        AlarmManager.INTERVAL_FIFTEEN_MINUTES,
        pendingIntent
    );
} catch(Exception e) {
    e.printStackTrace();
}

Une fois que vous avez diffusé le message ci-dessus Intent Vous pouvez recevoir votre Intent en mettant en œuvre un BroadcastReceiver . Notez que cela devra être enregistré soit dans votre manifeste d'application, soit par le biais de l'option context.registerReceiver(receiver, intentFilter); méthode. Pour plus d'informations sur BroadcastReceiver Veuillez vous référer à la documentation officielle. .

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent)
    {
        System.out.println("MyReceiver: here!") // Do your work here
    }
}

Si vous attendez moins de 10 minutes, je vous conseille d'utiliser une Handler .

final Handler handler = new Handler();
final int delay = 1000; // 1000 milliseconds == 1 second

handler.postDelayed(new Runnable() {
    public void run() {
        System.out.println("myHandler: here!"); // Do your work here
        handler.postDelayed(this, delay);
    }
}, delay);

133voto

Samir Mangroliya Points 21263

Utiliser la minuterie pour chaque seconde...

new Timer().scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        //your method
    }
}, 0, 1000);//put here time 1000 milliseconds=1 second

96voto

Umar Ata Points 1547

Vous pouvez essayer ce code pour appeler le gestionnaire toutes les 15 secondes via onResume() et l'arrêter lorsque l'activité n'est pas visible, via onPause().

Handler handler = new Handler();
Runnable runnable;
int delay = 15*1000; //Delay for 15 seconds.  One second = 1000 milliseconds.

@Override
protected void onResume() {
   //start handler as activity become visible

    handler.postDelayed( runnable = new Runnable() {
        public void run() {
            //do something

            handler.postDelayed(runnable, delay);
        }
    }, delay);

    super.onResume();
}

// If onPause() is not included the threads will double up when you 
// reload the activity 

@Override
protected void onPause() {
    handler.removeCallbacks(runnable); //stop handler when activity not visible
    super.onPause();
}

20voto

wdina Points 435

Si vous êtes familier avec RxJava, vous pouvez utiliser Observable.interval(), ce qui est très intéressant.

Observable.interval(60, TimeUnits.SECONDS)
          .flatMap(new Function<Long, ObservableSource<String>>() {
                @Override
                public ObservableSource<String> apply(@NonNull Long aLong) throws Exception {
                    return getDataObservable(); //Where you pull your data
                }
            });

L'inconvénient est que vous devez architecturer le sondage de vos données d'une manière différente. Cependant, la programmation réactive présente de nombreux avantages :

  1. Au lieu de contrôler vos données via un callback, vous créez un flux de données auquel vous vous abonnez. Cela permet de séparer la logique d'interrogation des données et la logique de remplissage de l'interface utilisateur avec vos données, de sorte que vous ne mélangez pas le code de la source de données et le code de l'interface utilisateur.
  2. Avec RxAndroid, vous pouvez gérer les threads en seulement 2 lignes de code.

    Observable.interval(60, TimeUnits.SECONDS)
          .flatMap(...) // polling data code
          .subscribeOn(Schedulers.newThread()) // poll data on a background thread
          .observeOn(AndroidSchedulers.mainThread()) // populate UI on main thread
          .subscribe(...); // your UI code

N'hésitez pas à consulter RxJava. Il a une courbe d'apprentissage élevée mais il rendra la gestion des appels asynchrones dans Android tellement plus facile et plus propre.

13voto

Luke Points 577

Avec Kotlin, nous pouvons maintenant créer une fonction générique pour cela !

object RepeatHelper {
    fun repeatDelayed(delay: Long, todo: () -> Unit) {
        val handler = Handler()
        handler.postDelayed(object : Runnable {
            override fun run() {
                todo()
                handler.postDelayed(this, delay)
            }
        }, delay)
    }
}

Et pour l'utiliser, il suffit de le faire :

val delay = 1000L
RepeatHelper.repeatDelayed(delay) {
    myRepeatedFunction()
}

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