web-dev-qa-db-fra.com

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

Je développe une application Android 2.3.3 et je dois exécuter une méthode toutes les X secondes .

Sur iOS, j'ai NSTimer , mais sous Android, je ne sais pas quoi utiliser.

Quelqu'un m'a recommandé gestionnaire ; un autre me recommande AlarmManager mais je ne sais pas quelle méthode convient le mieux à NSTimer .

Voici le code que je veux implémenter 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 recommandes-tu?

96
VansFannel

Cela dépend vraiment de combien de temps vous avez besoin d'exécuter la fonction.

Si c'est => 10 minutes → j'irais avec Alarm Manager.

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

Et puis vous recevez ces émissions via le récepteur de diffusion. Notez que cela devra être enregistré dans votre manifeste d'application ou via la méthode context.registerReceiver(receiver,filter);. Pour plus d'informations sur les récepteurs de diffusion, veuillez vous reporter à la documentation officielle. Récepteur de diffusion .

public class MyReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
         //do stuffs
    }
}

Si c'est = <10 minutes → j'irais avec un gestionnaire.

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

handler.postDelayed(new Runnable(){
    public void run(){
        //do something
        handler.postDelayed(this, delay);
    }
}, delay);
147
Jug6ernaut

Utilisez 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
91
Samir Mangroliya

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

Si vous connaissez RxJava, vous pouvez utiliser Observable.interval (), ce qui est très pratique.

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 qu'il faut que l'architecte interroge vos données d'une manière différente. Cependant, la méthode de programmation réactive présente de nombreux avantages:

  1. Au lieu de contrôler vos données via un rappel, vous créez un flux de données auquel vous êtes abonné. Cela sépare le problème de la logique "d'interrogation des données" et de la logique "remplir l'interface utilisateur avec vos données" afin que vous ne mélangiez pas votre code "source de données" et votre code d'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
    

S'il vous plaît vérifier RxJava. La courbe d’apprentissage est longue, mais le traitement des appels asynchrones dans Android est beaucoup plus simple et plus propre.

14
wdina
    new CountDownTimer(120000, 1000) {

        public void onTick(long millisUntilFinished) {
            txtcounter.setText(" " + millisUntilFinished / 1000);

        }

        public void onFinish() {

            txtcounter.setText(" TimeOut  ");
            Main2Activity.ShowPayment = false;
            EventBus.getDefault().post("go-main");

        }

    }.start();
3
Behzad F94

Ici, j'ai utilisé un fil dans onCreate () une activité à plusieurs reprises, le minuteur ne permet pas tout dans certains cas. Thread est la solution

     Thread t = new Thread() {
        @Override
        public void run() {
            while (!isInterrupted()) {
                try {
                    Thread.sleep(10000);  //1000ms = 1 sec
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {

                            SharedPreferences mPrefs = getSharedPreferences("sam", MODE_PRIVATE);
                            Gson gson = new Gson();
                            String json = mPrefs.getString("chat_list", "");
                            GelenMesajlar model = gson.fromJson(json, GelenMesajlar.class);
                            String sam = "";

                            ChatAdapter adapter = new ChatAdapter(Chat.this, model.getData());
                            listview.setAdapter(adapter);
                           // listview.setStackFromBottom(true);
                          //  Util.showMessage(Chat.this,"Merhabalar");
                        }
                    });

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    t.start();

En cas de besoin, il peut être arrêté par

@Override
protected void onDestroy() {
    super.onDestroy();
    Thread.interrupted();
    //t.interrupted();
}
2
Sam

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 utiliser, il suffit de faire:

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