Domanda

Ho un Gestore dal mio sub-Attività che è stato chiamato dalla principale Attività.Questo Gestore è usato da sub-classi di postDelay alcuni Runnables, e non riesco a gestirli.Ora, in onStop l'evento, ho bisogno di rimuoverli prima di terminare l'Attività (in qualche modo ho chiamato finish(), ma ancora chiamare di nuovo e di nuovo).Esiste un modo per rimuovere tutte le richiamate da un Gestore?

È stato utile?

Soluzione

Nella mia esperienza chiamarlo ha funzionato alla grande!

handler.removeCallbacksAndMessages(null);

Nei documenti per RemoveCallbacks essages dice ...

Rimuovi eventuali posti in sospeso di callback e inviati messaggi il cui OBJ è token. Se il token è null, tutti i callback e i messaggi verranno rimossi.

Altri suggerimenti

Per qualsiasi specifico Runnable istanza, chiama Handler.removeCallbacks(). Si noti che utilizza il Runnable istanza stessa per determinare quali callbacks non registrarsi, quindi se si creano una nuova istanza ogni volta che viene effettuato un post, devi assicurarti di avere riferimenti all'esatto Runnable per cancellare. Esempio:

Handler myHandler = new Handler();
Runnable myRunnable = new Runnable() {
    public void run() {
        //Some interesting task
    }
};

Puoi chiamare myHandler.postDelayed(myRunnable, x) per pubblicare un altro callback alla coda dei messaggi in altri punti del codice e rimuovere tutti i callback in sospeso myHandler.removeCallbacks(myRunnable)

Sfortunatamente, non puoi semplicemente "cancellare" l'intero MessageQueue per un Handler, anche se fai una richiesta per il MessageQueue Oggetto ad esso associato perché i metodi per l'aggiunta e la rimozione di elementi sono protetti dal pacchetto (solo le classi all'interno del pacchetto Android.os possono chiamarli). Potrebbe essere necessario creare un sottile Handler sottoclasse per gestire un elenco di Runnables come vengono pubblicati/eseguiti ... o guarda un altro paradigma per passare i tuoi messaggi tra ciascuno Activity

Spero possa aiutare!

Se non hai i riferimenti eseguibili, al primo callback, ottieni l'OBJ del messaggio e usa removeCallbackSandMessages () Per rimuovere tutti i callback correlati.

Definire un nuovo gestore e correre:

private Handler handler = new Handler(Looper.getMainLooper());
private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            // Do what ever you want
        }
    };

Chiama il post ritardato:

handler.postDelayed(runnable, sleep_time);

Rimuovi il callback dal gestore:

handler.removeCallbacks(runnable);

Si prega di notare che si dovrebbe definire a Handler e a Runnable Nell'ambito di classe, in modo che sia creato una volta.removeCallbacks(Runnable) Funziona correttamente a meno che non li non definisca più volte. Si prega di guardare i seguenti esempi per una migliore comprensione:

Modo errato:

    public class FooActivity extends Activity {
           private void handleSomething(){
                Handler handler = new Handler();
                Runnable runnable = new Runnable() {
                   @Override
                   public void run() {
                      doIt();
                  }
               };
              if(shouldIDoIt){
                  //doIt() works after 3 seconds.
                  handler.postDelayed(runnable, 3000);
              } else {
                  handler.removeCallbacks(runnable);
              }
           }

          public void onClick(View v){
              handleSomething();
          }
    } 

Se chiami onClick(..) Metodo, non ti fermi mai doIt() Metodo che chiama prima di chiamare. Perché ogni volta crea new Handler e new Runnable istanze. In questo modo, hai perso i riferimenti necessari a cui appartengono gestore e Runnable istanze.

Modo corretto :

 public class FooActivity extends Activity {
        Handler handler = new Handler();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                doIt();
            }
        };
        private void handleSomething(){
            if(shouldIDoIt){
                //doIt() works after 3 seconds.
                handler.postDelayed(runnable, 3000);
            } else {
                handler.removeCallbacks(runnable);
            }
       }

       public void onClick(View v){
           handleSomething();
       }
 } 

In questo modo, non hai perso riferimenti reali e removeCallbacks(runnable) funziona con successo.

La frase chiave è quella 'Definiscili come globali nel tuo Activity o Fragment quello che usi '.

Come josh527 ha detto, handler.removeCallbacksAndMessages(null); può funzionare.
Ma perché?
Se hai un occhiata al codice sorgente, è possibile comprendere più chiaramente.Ci sono 3 tipo di metodo per rimuovere callback/messaggi dal gestore(il MessageQueue):

  1. rimuovere dalla callback (e token)
  2. rimuovere dal messaggio.che cosa (e token)
  3. rimuovere dal token

Handler.java (lasciare qualche metodo di overload)

/**
 * Remove any pending posts of Runnable <var>r</var> with Object
 * <var>token</var> that are in the message queue.  If <var>token</var> is null,
 * all callbacks will be removed.
 */
public final void removeCallbacks(Runnable r, Object token)
{
    mQueue.removeMessages(this, r, token);
}

/**
 * Remove any pending posts of messages with code 'what' and whose obj is
 * 'object' that are in the message queue.  If <var>object</var> is null,
 * all messages will be removed.
 */
public final void removeMessages(int what, Object object) {
    mQueue.removeMessages(this, what, object);
}

/**
 * Remove any pending posts of callbacks and sent messages whose
 * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
 * all callbacks and messages will be removed.
 */
public final void removeCallbacksAndMessages(Object token) {
    mQueue.removeCallbacksAndMessages(this, token);
}

MessageQueue.java fare il lavoro vero e proprio:

void removeMessages(Handler h, int what, Object object) {
    if (h == null) {
        return;
    }

    synchronized (this) {
        Message p = mMessages;

        // Remove all messages at front.
        while (p != null && p.target == h && p.what == what
               && (object == null || p.obj == object)) {
            Message n = p.next;
            mMessages = n;
            p.recycleUnchecked();
            p = n;
        }

        // Remove all messages after front.
        while (p != null) {
            Message n = p.next;
            if (n != null) {
                if (n.target == h && n.what == what
                    && (object == null || n.obj == object)) {
                    Message nn = n.next;
                    n.recycleUnchecked();
                    p.next = nn;
                    continue;
                }
            }
            p = n;
        }
    }
}

void removeMessages(Handler h, Runnable r, Object object) {
    if (h == null || r == null) {
        return;
    }

    synchronized (this) {
        Message p = mMessages;

        // Remove all messages at front.
        while (p != null && p.target == h && p.callback == r
               && (object == null || p.obj == object)) {
            Message n = p.next;
            mMessages = n;
            p.recycleUnchecked();
            p = n;
        }

        // Remove all messages after front.
        while (p != null) {
            Message n = p.next;
            if (n != null) {
                if (n.target == h && n.callback == r
                    && (object == null || n.obj == object)) {
                    Message nn = n.next;
                    n.recycleUnchecked();
                    p.next = nn;
                    continue;
                }
            }
            p = n;
        }
    }
}

void removeCallbacksAndMessages(Handler h, Object object) {
    if (h == null) {
        return;
    }

    synchronized (this) {
        Message p = mMessages;

        // Remove all messages at front.
        while (p != null && p.target == h
                && (object == null || p.obj == object)) {
            Message n = p.next;
            mMessages = n;
            p.recycleUnchecked();
            p = n;
        }

        // Remove all messages after front.
        while (p != null) {
            Message n = p.next;
            if (n != null) {
                if (n.target == h && (object == null || n.obj == object)) {
                    Message nn = n.next;
                    n.recycleUnchecked();
                    p.next = nn;
                    continue;
                }
            }
            p = n;
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top