2009-12-28 5 views
12

Il mio problema è che ho bisogno di inviare messaggi con un ritardo di 1 secondo. Il conduttore inizia quindi un'azione, ottieni l'immagine.Come eliminare i messaggi in ritardo prima che arrivino a un gestore?

Esistono tuttavia alcune condizioni in cui il messaggio già inviato deve essere eliminato (prima del secondo trascorso) per impedire al gestore di eseguire operazioni. Non riuscivo a capire come fare questo (o se è anche possibile), quindi se qualcuno di voi ha un indizio, per favore fatemelo sapere ..

risposta

35

Non c'è niente di spaventoso nei metodi removeMessages(); sono perfettamente al sicuro. Il framework si basa in gran parte su questi metodi e sono utilizzati in molti posti, specialmente nei widget predefiniti (View, ListView, ecc.) È molto meglio che creare un Handler che ignora i messaggi specifici. Questa è la programmazione, non andare con i tuoi sentimenti: p

+0

Sarebbe utile se ci fosse più documentazione su questi metodi, se il parametro "cosa" fosse disponibile su tutti i meccanismi di aggancio (es. PostRunnable()), se la distinzione tra "cosa" e "token" fosse più chiara, ecc. Se devo frugare attraverso il codice sorgente di Android per capire cosa sta facendo Handler oggi, ciò significa che non ho garanzie che tale comportamento non documentato rimarrà coerente domani. Quindi, removeMessages() sono, IMHO, spaventosi per gli sviluppatori su cui fare affidamento. Non ci vorrà molto per chiarire questo, ma non posso prendere decisioni per ciò che è e non è un comportamento appropriato dell'handler. – CommonsWare

+0

che la tua ultima frase ha reso la mia giornata, chiaramente. Però, inoltre, sono d'accordo con il fatto che la documentazione è davvero insufficiente in quel campo, forse dovrei semplicemente presentare un ticket. – moritz

+1

Non c'è motivo di avere un "cosa" quando pubblichi un Runnable, devi solo rimuovere removeCallback() per questo. Che cosa esattamente non è garantito dalla documentazione? –

5

Molti sviluppatori e gran parte del codice sorgente che troverai mostreranno le persone che passano funzioni anonime a un gestore, quindi penso che in alcuni casi potresti essere incerto su come per rimuovere questi. Una soluzione semplice è dichiarare il tuo eseguibile come faresti con qualsiasi altro oggetto e mantenere un puntatore ad esso che può essere usato per cancellare qualsiasi istanza dalla coda del Gestore.

private Runnable lastMyRunnablePtr = null; 

...

private class MyRunnable implements Runnable 
{} 

....

lastMyRunnablePtr = new MyRunnable(); 
mHandler.postDelayed(lastMyRunnablePtr ,30000); 

....

protected void onDestroy() { 
    mHandler.removeCallbacks(lastMyRunnablePtr); 
} 
0

In realtà, si dovrebbe prendere in considerazione l'attuazione di handler.removeMessages(int, obj). Se obj è un oggetto correlato all'autoboxing, si verificherà un problema di implementazione di Android MessageQueue.

Per il seguente snippet di codice, removeMessages non funzionerà come risultato del boxing automatico, boxing-conversion e l'implementazione di MessageQueue utilizzando p.obj == oggetto per confrontare l'oggetto.

Message msg = handler.obtainMessage(what, 256); 
handler.sendMessageDelayed(message, delayMillis); 
handler.removeMessages(what, 256); 

Ref questo post.

Problemi correlati