Abbrechen eines handler.postdelayed-Prozesses

259

Ich verwende handler.postDelayed(), um eine Wartezeit zu erstellen, bevor die nächste Phase meiner App stattfindet. Während der Wartezeit wird ein Dialogfeld mit Fortschrittsbalken und Abbrechen- Schaltfläche angezeigt.

Mein Problem ist, dass ich keine Möglichkeit finden kann, die postDelayed- Aufgabe vor Ablauf der Zeit abzubrechen .

Ron
quelle
Hoffe, diese Hilfe hilft gist.github.com/imammubin/a587192982ff8db221da14d094df6fb4 MainActivity als Screen Launcher mit Handler & Runable-Funktion, der Runnable Run-to-Login-Seite oder Feed-Seite mit Basiseinstellungs-Login-Benutzer mit Firebase.
Mubin

Antworten:

479

Ich mache das, um eine verzögerte Runnable zu posten:

myHandler.postDelayed(myRunnable, SPLASH_DISPLAY_LENGTH); 

Und das, um es zu entfernen: myHandler.removeCallbacks(myRunnable);

Varun
quelle
74
Wenn Sie es sich leisten können, alle Rückrufe und Nachrichten auf dem Handler abzubrechen und keine Verweise auf die ausführbare Datei behalten möchten, ist der dritte Punkt in der akzeptierten Antwort auf diese Frage eine weitere Alternative, die für meinen Fall ohnehin zu funktionieren scheint: Stackoverflow. com / Fragen / 11299440 /… (im Wesentlichen myHandler.removeCallbacksAndMessages (null) aufrufen;)
Mick
removeCallbacksAndMessages kann den Trick machen, aber ich persönlich bevorzuge die Kontrolle über die geplanten Runnables. Das Instanziieren und Behandeln von zwei Runnables führt nicht zu einer Beeinträchtigung der App-Leistung. Andernfalls benötigen Sie möglicherweise etwas Stärkeres, imho, wenn Sie mehr als zwei oder drei Runnables benötigen.
andrea.rinaldi
59

Falls Sie mehrere innere / anonyme Runnables an denselben Handler übergeben haben und alle bei derselben Ereignisverwendung abbrechen möchten

handler.removeCallbacksAndMessages(null);

Gemäß Dokumentation,

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.

Mani
quelle
Dadurch werden alle ausführbaren Rückrufe einmal entfernt. Andernfalls rufen Sie removeCallbacks(callback) an, um einen bestimmten Rückruf zu entfernen
FindOutIslamNow
18

Eine andere Möglichkeit besteht darin, das Runnable selbst zu handhaben:

Runnable r = new Runnable {
    public void run() {
        if (booleanCancelMember != false) {
            //do what you need
        }
    }
}
codeScriber
quelle
14
Müsste booleanCancelMember nicht endgültig sein, was bedeutet, dass es nicht geändert werden kann und daher für diesen Zweck unbrauchbar ist?
Stealthcopter
9
@stealthcopter nein muss es nicht sein.
Benoit Jadinon
7
@pablisco Es muss nicht endgültig sein, auch wenn das Runnable anonym ist. Es kann Mitglied in der einschließenden Klasse sein.
Martin
6
Nicht abstimmen, aber vorsichtig sein. Wenn bei diesem Ansatz mehrere Runnables verzögert veröffentlicht werden, kann dies zu unangenehmen Rennbedingungen führen. Dadurch wird die ausführbare Datei nicht abgebrochen. Ob dieser Code ausgeführt wird oder nicht, hängt also vom Wert von booleanCancelMember zum jeweiligen Zeitpunkt für jede veröffentlichte ausführbare Datei ab. Was schnell unvorhersehbar werden kann.
Dennis K
1
Wenn der Runnable NICHT anonym ist, bedeutet dies, dass ich ( rin diesem Fall) einen Verweis darauf habe, was bedeutet, dass ich ihn verwenden kann myHandler.removeCallbacks(r);. Wenn der Runnable anonym ist, ist das Flag ein Mitglied in der einschließenden Klasse, was bedeutet, dass ich einen Verweis auf dieses Objekt benötige, um das Flag zu ändern, was bedeutet, dass ich rsowieso wieder haben muss, was bedeutet, dass ich es tun kann myHandler.removeCallbacks(r);. Und wenn ich das tue, myHandler.removeCallbacks(r);ist eine solche Flagge überhaupt nicht notwendig. Vermisse ich etwas
Nacho4d
1

Hier ist eine Klasse, die eine Abbruchmethode für eine verzögerte Aktion bereitstellt

public class DelayedAction {

private Handler _handler;
private Runnable _runnable;

/**
 * Constructor
 * @param runnable The runnable
 * @param delay The delay (in milli sec) to wait before running the runnable
 */
public DelayedAction(Runnable runnable, long delay) {
    _handler = new Handler(Looper.getMainLooper());
    _runnable = runnable;
    _handler.postDelayed(_runnable, delay);
}

/**
 * Cancel a runnable
 */
public void cancel() {
    if ( _handler == null || _runnable == null ) {
        return;
    }
    _handler.removeCallbacks(_runnable);
}}
Stéphane Padovani
quelle
0

Es hat bei mir funktioniert, als ich CancelCallBacks (this) innerhalb des Post-Delayed Runnable aufgerufen habe, indem ich es über einen Booleschen Wert übergeben habe

Runnable runnable = new Runnable(){
    @Override
    public void run() {
        Log.e("HANDLER", "run: Outside Runnable");
        if (IsRecording) {
            Log.e("HANDLER", "run: Runnable");
            handler.postDelayed(this, 2000);
        }else{
            handler.removeCallbacks(this);
        }
    }
};
Ramin Fallahzadeh
quelle
3
Ihr Code enthält keine "CancelCallBacks". Vielleicht, weil es nicht existiert? :)
Der unglaubliche