J'appelle depuis une méthode:
myHandler.postDelayed(mMyRunnableHide, 6000);
qui appelle:
public Runnable mMyRunnableHide = new Runnable()
{
public void run()
{
mTextDisplay.setText("");
DisplayX();
}
};
si un bouton à l'écran est cliqué, je veux arrêter le runnable:
Button next = (Button) findViewById(R.id.Breaction);
next.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
myHandler.removeCallbacks(mMyRunnableHide);
mTextDisplay.setText("");
DisplayX();
}
});
}
le removecallbacks n'arrête pas le runnable. Qu'est-ce que je fais mal? Est-ce que j'utilise la bonne méthode? Je veux juste que le runnable "Non Run" quand l'utilisateur clique sur le bouton.
Merci pour toute aide.
Handler.removeCallback
est synchrone et fonctionnera bien si:
postDelayed
toujours dans le thread principal.removeCallback
toujours dans le thread principalpostDelayed
après avoir supprimé les rappels.Donc, dans votre cas, removeCallbacks
est appelé à partir d'un gestionnaire de boutons, qui s'exécute dans le thread principal. Mais vous n'avez pas indiqué dans votre code le point d'où vous appelez postDelayed
. Si vous appelez cela depuis un fil d’arrière-plan, c’est là que réside votre problème.
Si vous êtes certain de n'appeler aucune de ces méthodes à partir de threads d'arrière-plan et que l'ordre des appels est correct, vous risquez de laisser des tâches non annulées en vie du fait de la recréation d'activités sur des modifications de configuration (rotation d'écran, etc.). Assurez-vous toujours d'appeler à nouveau removeCallbacks
dans la méthode onDestroy
pour éviter ce genre de problème.
Voici une autre façon d'accomplir ce que décrit mtmurdock. Cette classe permettra d’éditer les variables d’instance dans toutes les classes pour lesquelles votre Runnable est définie en tant que classe interne anonyme.
package support;
/**
* Runnable that can be stopped from executing
*/
public abstract class KillableRunnable implements Runnable{
private boolean isKilled=false;
/**
* Instead of Overriding run(), override this method to perform a Runnable operation.
* This will allow editing instance variables in the class that this Runnable is defined
*/
public abstract void doWork();
//The handler that posts this Runnable will call this method.
//By default, check if it has been killed. doWork() will now be the method
//override to implement this Runnable
@Override
final public void run(){
if(!isKilled){
doWork();
}
}
final public void kill(){
isKilled=true;
}
}
Je ne pense pas que removeCallbacks (..) arrête uniquement les messages en attente (Runnables) , Je pense que removeCallbacks (..) ne fonctionne pas pour une autre raison, mais je ne le sais pas. parce que postDelayed (..) et removeCallbacks (..) sont dans le même fil