72 votes

Comment supprimer un runnable d'un objet handler ajouté par postDelayed ?

J'ai un "ouvert" et j'utilise Handler.postDelayed(Runnable, delay) pour déclencher un "fermer" animation après un court délai. Cependant, pendant le temps entre l'ouverture et la fermeture, il y a éventuellement une autre animation déclenchée par un clic.

Ma question est la suivante : comment puis-je annuler le "fermer" dans le gestionnaire ?

0 votes

Attention à cette réponse si vous utilisez Kotlin : stackoverflow.com/a/30905295/2736039 J'ai essayé et j'ai rencontré ce problème (uniquement en Kotlin) : stackoverflow.com/questions/62405834/

102voto

Cristian Points 92147

Il suffit d'utiliser le removeCallbacks(Runnable r) méthode.

10 votes

Est-il possible de supprimer les callbacks pour les runnables anonymes ?

10 votes

Je ne pense pas... vous devrez utiliser des non-anonymes. Sinon, vous ne pourrez pas les référencer à l'avenir.

3 votes

Voir la réponse de @NameSpace. Vous pouvez supprimer les exécutables en attente si vous publiez l'exécutable avec un jeton. Vous pouvez également utiliser la méthode de Daniel L. pour supprimer tous les callbacks/messages en utilisant un jeton nul.

98voto

Daniel L. Points 1687

La réponse de Cristian est correcte, mais contrairement à ce qui est indiqué dans les commentaires de la réponse, vous pouvez en fait supprimer les rappels pour les données anonymes. Runnables en appelant removeCallbacksAndMessages(null);

Comme indiqué aquí :

Supprime tous les messages en attente des callbacks et des messages envoyés dont l'obj est token. Si le jeton est nul, tous les callbacks et les messages seront supprimés. .

17voto

NameSpace Points 2626

C'est une réponse tardive, mais voici une méthode différente pour les cas où vous ne voulez supprimer qu'une catégorie spécifique d'exécutables du gestionnaire (c'est-à-dire, dans le cas de l'OP, supprimer seulement l'animation de fermeture, en laissant les autres exécutables dans la file d'attente) :

    int firstToken = 5;
    int secondToken = 6;

    //r1 to r4 are all different instances or implementations of Runnable.  
    mHandler.postAtTime(r1, firstToken, 0);
    mHandler.postAtTime(r2, firstToken, 0);
    mHandler.postAtTime(r3, secondToken, 0);

    mHandler.removeCallbacksAndMessages(firstToken);

    mHandler.postAtTime(r4, firstToken, 0);

Le code ci-dessus exécutera "r3" et ensuite "r4" seulement. Cela vous permet de supprimer une catégorie spécifique de runnables définis par votre jeton, sans avoir besoin de détenir des références aux runnables eux-mêmes.

Remarque : le code source compare les jetons en utilisant uniquement l'opérande "==" (il n'appelle pas .equals()), il est donc préférable d'utiliser des ints/Integers plutôt que des chaînes de caractères pour le jeton.

11voto

robisaks Points 68

Si vous utilisez la récursion, vous pouvez y parvenir en passant "this". Voir le code ci-dessous.

public void countDown(final int c){
    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            aq.id(R.id.timer).text((c-1)+"");
            if(c <= 1){
                aq.id(R.id.timer).gone();
                mHandler.removeCallbacks(this);
            }else{
                countDown(c-1);
            }
        }
    }, 1000);
}

Cet exemple va définir le texte d'un TextView (timer) toutes les secondes, en effectuant un compte à rebours. Lorsqu'il arrive à 0, il supprime le TextView de l'interface utilisateur et désactive le compte à rebours. Ceci n'est utile que pour quelqu'un qui utilise la récursion, mais je suis arrivé ici en cherchant cela, donc je poste mes résultats.

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