2009-12-28 13 views
12

Mon problème est que je dois envoyer des messages avec un retard de 1 seconde. Le gestionnaire initie alors une action, vous obtenez l'image.Comment faire pour supprimer les messages retardés avant qu'ils arrivent à un gestionnaire?

Il existe néanmoins certaines conditions dans lesquelles le message déjà envoyé doit être supprimé (avant que le second ne soit écoulé) pour empêcher le gestionnaire de faire quoi que ce soit. Je ne pouvais pas comprendre comment faire cela (ou si c'est même possible), donc si quelqu'un d'entre vous a un indice, s'il vous plaît faites le moi savoir ..

Répondre

35

Il n'y a rien d'effrayant sur les méthodes removeMessages(); ils sont parfaitement sûrs. Le framework s'appuie fortement sur ces méthodes et elles sont utilisées dans de nombreux endroits, notamment dans les widgets par défaut (View, ListView, etc.). C'est beaucoup mieux que de construire un Handler qui ignore des messages spécifiques. Ceci est la programmation, ne pas aller avec vos sentiments: p

+0

Cela aiderait s'il y avait plus de documentation sur ces méthodes, si le paramètre 'what' était disponible sur tous les mécanismes de mise en file d'attente (par exemple postRunnable()), si la distinction entre 'what' et 'token' était plus claire Si je dois fouiller dans le code source d'Android pour comprendre ce que fait Handler aujourd'hui, cela signifie que je n'ai aucune garantie qu'un tel comportement non documenté restera cohérent demain. Par conséquent, removeMessages() sont, à mon humble avis, effrayant pour les développeurs à compter sur. Il ne faudra pas grand-chose pour éclaircir cela, mais je ne peux pas prendre de décisions pour ce qui est et ce qui ne convient pas. – CommonsWare

+0

cette dernière phrase de la vôtre a fait ma journée, clairement. Mais d'ailleurs, je suis également d'accord avec commonsaware que la documentation est vraiment insuffisante dans ce domaine, peut-être que je devrais simplement déposer un ticket. – moritz

+1

Il n'y a aucune raison d'avoir un "quoi" quand vous postez un Runnable, vous utilisez simplement removeCallback() pour cela. Qu'est-ce qui n'est pas garanti dans la documentation? –

5

Beaucoup de développeurs et une grande partie du code source que vous trouverez montrera les gens passant des fonctions anonymes à un gestionnaire, donc je pense que dans certains cas, vous ne savez pas comment pour les enlever. Une solution simple consiste à déclarer votre runnable comme vous le feriez pour n'importe quel autre objet, et à conserver un pointeur qui peut être utilisé pour effacer n'importe quelle instance de la file d'attente du gestionnaire.

private Runnable lastMyRunnablePtr = null; 

...

private class MyRunnable implements Runnable 
{} 

....

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

....

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

En fait, vous devriez envisager la mise en œuvre de handler.removeMessages(int, obj). Si l'obj est un objet lié à l'autoboxing, vous rencontrerez un problème d'implémentation de l'android MessageQueue. Pour l'extrait de code suivant, removeMessages ne fonctionnera pas à la suite de la saisie automatique, boxing-conversion et l'implémentation de MessageQueue à l'aide de l'objet p.obj == pour comparer l'objet.

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

Ref cette post.