Wie entferne ich eine ausführbare Datei aus einem von postDelayed hinzugefügten Handlerobjekt?


70

Ich habe eine "offene" Animation und verwende Handler.postDelayed(Runnable, delay), um nach einer kurzen Verzögerung eine "geschlossene" Animation auszulösen . In der Zeit zwischen Öffnen und Schließen wird möglicherweise eine andere Animation durch einen Klick ausgelöst.

Meine Frage ist, wie würde ich die "Schließen" -Animation im Handler abbrechen ?


Seien Sie vorsichtig mit dieser Antwort, wenn Sie Kotlin verwenden: stackoverflow.com/a/30905295/2736039 , ich habe das versucht und bin auf dieses Problem gestoßen
Ultimo_m

Antworten:


99

Verwenden Sie einfach die removeCallbacks(Runnable r)Methode.


10
Ist es möglich, Rückrufe für anonyme ausführbare Dateien zu entfernen?
Bruce Lee

10
Ich glaube nicht ... Sie müssen nicht anonyme verwenden. Andernfalls können Sie sie in Zukunft nicht mehr referenzieren.
Cristian

3
Siehe die Antwort von @ NameSpace. Sie können ausstehende ausführbare Dateien entfernen, wenn Sie die ausführbare Datei mit einem Token veröffentlichen. Oder Sie können die Methode von Daniel L. verwenden, um alle Rückrufe / Nachrichten mit einem Null-Token zu entfernen.
Vman

Gibt es Empfehlungen zum Entfernen bestimmter Rückrufe für APIs, bei denen removeCallbacks (Runnable r) nicht verfügbar war?
GOM1

Entfernt dies alle Vorkommen der Instanz? Weil ich es mehrmals mit unterschiedlichen Verzögerungszeiten
poste

96

Die Antwort von Cristian ist korrekt, aber im Gegensatz zu den Kommentaren in der Antwort können Sie Rückrufe für anonyme RunnablesAnrufe entfernenremoveCallbacksAndMessages(null);

Wie hier angegeben :

Entfernen Sie alle ausstehenden Posts von Rückrufen und gesendeten Nachrichten, deren Objekt ein Token ist. Wenn das Token null ist, werden alle Rückrufe und Nachrichten entfernt .


5
Ich möchte nur darauf hinweisen, dass dieses Verhalten anders ist, egal ob Sie es mit einer Handleroder einer ViewKlasse zu tun haben . In einer ViewKlasse (und möglicherweise nach 4.0?) Müssen Sie dasselbe RunnableObjekt verwenden, um die Aufgabe abzubrechen, während bei einer HandlerKlasse einfach alle abgebrochen werden, wenn Sie bestehen null. Die Frage gibt jedoch a an, Handlersodass Ihre Antwort korrekt ist.
Andre

1
Ja wirklich!! danke .. hatte da etwas lauffähiges und removeCallbacks hat einfach nichts gemacht !!!!! aber das hat wirklich geklappt :) thx
cV2

17

Dies ist eine späte Antwort, aber hier ist eine andere Methode, wenn Sie nur eine bestimmte Kategorie von Runnables aus dem Handler entfernen möchten (dh im Fall von OP entfernen Sie einfach die Schließen-Animation und lassen andere Runnables in der Warteschlange):

    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);

Der obige Code führt nur "r3" und dann nur "r4" aus. Auf diese Weise können Sie eine bestimmte Kategorie von Runnables entfernen, die von Ihrem Token definiert wurden, ohne Verweise auf die Runnables selbst enthalten zu müssen.

Hinweis: Der Quellcode vergleicht Token nur mit dem Operanden "==" (er ruft nicht .equals () auf). Verwenden Sie daher am besten Ints / Integer anstelle von Zeichenfolgen für das Token.


Ich habe Ihre Antwort gesehen und bin von stringzu gewechselt intund hatte dann einen Tag lang diesen Fehler: D stackoverflow.com/q/62405834/2736039
Ultimo_m

Dies wird in Kotlin für int> 127 nicht funktionieren, nur diesen Kommentar hier als Hinweis für zukünftige Leser zu
hinterlassen

10

Wenn Sie eine Rekursion verwenden, können Sie dies erreichen, indem Sie "this" übergeben. Siehe Code unten.

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);
}

In diesem Beispiel wird der Text einer Textansicht (Timer) jede Sekunde heruntergezählt. Sobald 0 erreicht ist, wird die Textansicht von der Benutzeroberfläche entfernt und der Countdown deaktiviert. Dies ist nur für jemanden nützlich, der Rekursion verwendet, aber ich bin hier angekommen, um danach zu suchen, also veröffentliche ich meine Ergebnisse.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.