web-dev-qa-db-fra.com

Android - Exécution périodique d'une méthode à l'aide de l'appel postDelayed ()

J'ai une situation dans une application Android) dans laquelle je souhaite démarrer une activité réseau (envoi de données) qui doit s'exécuter toutes les secondes. Pour ce faire, procédez comme suit:

Dans le onCreate() j'ai le code:

tv = new TextView(this);
tv.postDelayed(sendData, 1000);

La sendData() fonction:

   Handler handler = new Handler();
   private Runnable sendData=new Runnable(){
    public void run(){
        try {
            //prepare and send the data here..
            handler.removeCallbacks(sendData);
            handler.postDelayed(sendData, 1000);    
        }
        catch (Exception e) {
            e.printStackTrace();
        }   
    }
};

Le problème vient comme ceci: lorsque l’utilisateur appuie sur les boutons précédents et que l’application apparaît (l’interface utilisateur disparaît), la fonction sendData() est toujours exécutée, ce que je veux. Désormais, lorsque l'utilisateur redémarre l'application, ma onCreate() est appelée à nouveau et la personne sendData() est invoquée deux fois par seconde. Ça continue comme ça. Chaque fois que l'utilisateur revient et recommence, il se produit une sendData() par seconde supplémentaire.

Qu'est-ce que je fais mal? Est-ce mon problème de création de new Handler()? Quelle est la meilleure façon de gérer cela? Je veux un sendData() appel par seconde jusqu'à ce que l'utilisateur quitte l'application (gestionnaire de l'application de formulaire).

41
zolio

Pourquoi ne créez-vous pas de service et ne mettez-vous pas la logique dans onCreate(). Dans ce cas, même si vous appuyez sur le bouton Précédent, le service continuera à s'exécuter. et une fois que vous entrez dans l'application, il n'appellera plus onCreate(). Plutôt, il appellera onStart()

27
Vipul Shah
final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
      @Override
      public void run() {
        //Do something after 100ms
        Toast.makeText(c, "check", Toast.LENGTH_SHORT).show();  
        handler.postDelayed(this, 2000);
      }
    }, 1500);
96
Saad Asad

Peut-être impliquer les méthodes de cycle de vie de l'activité pour y parvenir:

Handler handler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      handler.post(sendData);
}

@Override
protected void onDestroy() {
      super.onDestroy();
      handler.removeCallbacks(sendData);
}


private final Runnable sendData = new Runnable(){
    public void run(){
        try {
            //prepare and send the data here..


            handler.postDelayed(this, 1000);    
        }
        catch (Exception e) {
            e.printStackTrace();
        }   
    }
};

Dans cette approche, si vous appuyez sur la touche touche de retour de votre activité ou appelez finish();, les appels postDelayed seront également arrêtés.

27
waqaslam

Vous pouvez simplifier le code comme ceci.

En Java:

new Handler().postDelayed (() -> {
    //your code here
}, 1000);

À Kotlin:

Handler().postDelayed({
   //your code here
}, 1000)
12
Varun Chandran

Veuillez vérifier ci-dessous son fonctionnement de mon côté dans le code ci-dessous, votre gestionnaire s'exécutera après chaque seconde lorsque vous êtes sur la même activité.

 HandlerThread handlerThread = new HandlerThread("HandlerThread");
                handlerThread.start();
                handler = new Handler(handlerThread.getLooper());
                runnable = new Runnable()
                {
                    @Override
                    public void run()
                    {

                            handler.postDelayed(this, 1000);
                        }
                };
                handler.postDelayed(runnable, 1000);
2
sharma_kunal
Handler h = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (msg.what==0){
            // do stuff
            h.removeMessages(0);  // clear the handler for those messages with what = 0
            h.sendEmptyMessageDelayed(0, 2000); 
        }
    }
};


 h.sendEmptyMessage(0);  
1
Dan Alboteanu

Je pense que vous pourriez expérimenter différents indicateurs d'activité, car cela ressemble à plusieurs instances.

"singleTop" "singleTask" "singleInstance"

Sont ceux que je voudrais essayer, ils peuvent être définis à l'intérieur du manifeste.

http://developer.Android.com/guide/topics/manifest/activity-element.html

0
Tony

Vous devez définir andrid: allowRetainTaskState = "true" pour lancer l'activité dans le fichier Manifest.xml. Si cette activité n'est pas une activité de lancement. vous devez définir Android: launchMode = "singleTask" à cette activité

0
Folee