6
votes

Exécutez tous les runnables programmés (postdelayed) dans le gestionnaire

J'utilise un gestionnaire, qui publie quelques exécubles via postdelayed (r, retard_time) , mais j'ai besoin d'exécuter tout runnables avant de poster Nouveau via postdelayed .

Toutes les bonnes idées Comment y parvenir aussi simple que possible?

EDIT:

Je veux essentiellement comme ça: < / p> xxx


8 commentaires

Puis-je demander pourquoi' ? Parce que ce que vous voulez faire sonne comme une si mauvaise idée qu'il pourrait être utile de tenter de comprendre la raison pour laquelle vous voudrez peut-être faire cela? Je veux dire: il est parfaitement possible que quelqu'un utilisant le même gestionnaire attendra un message et que la file d'attente ne sera jamais vide pour vous. Dans ce cas, vous ramèneriez la file d'attente asynchrone à un état de synchronouse dans votre fil, avec toutes les personnes non-sifflettes potentielles.


C'est tout à fait impossible, que la file d'attente ne sera jamais vide, car vous ne pouvez pas supprimer des articles infiniment. C'est parce que je veux des suppressions de base de données ondulables. Le ListItem doit être supprimé pour l'utilisateur, mais en réalité, il est supprimé après 5 secondes. Je souhaite flush / faire toutes les requêtes de base de données car lorsque l'utilisateur annule une action ou supprimez une autre, ils ne devraient pas réapparaître dans la liste de liste (qu'ils le feraient, car ils ne sont pas supprimés, seule la vue est supprimée de la liste de réception) . C'est assez compliqué, si vous avez une autre idée, dites-le-moi! ;)


Écrivez votre propre file d'attente. Essayer de recycler les gestionnaires pour cela pourrait être un peu difficile. Une bonne approche consiste également à énumérer des messages afin que vous puissiez directement rejeter le numéro de message X '


Je n'utilise actuellement qu'un seul gestionnaire, je n'ai pas besoin de recycler les gestionnaires. Je peux énumérer les messages, car j'ai une faiblesse pour les runnables dans une arracheListe pour annuler les runnables. Je peux supprimer tous les messages, mais cela ne m'aide pas, je dois les appeler. Cependant, vous m'avérez une idée: je pourrais supprimer les runnables du gestionnaire d'original et les poster immédiatement sur une autre. ;)


... ou avoir 1 runnabel qui inspecte une autre file d'attente et des chiffres sur quoi faire. Pourquoi le rend-tu si compliqué?


Je mettant également en œuvre des fonctionnalités d'annulation de la même manière que @leandros. D'après ce que je comprends, il est également important de chasser la file d'attente du message du gestionnaire lorsque Onpaused est appelé votre activité. Sinon, les messages en file d'attente ne peuvent jamais être exécutés. Les gestionnaires sont-ils simplement le mauvais outil pour le travail? Si oui, que devrions-nous utiliser à la place?


@XAVI J'utilise réellement des gestionnaires, je peux poster ma solution demain si vous le souhaitez.


Vous devez accepter une réponse.


3 Réponses :


0
votes

Eh bien, tous les Runnable code> S sont exécutés sur une file d'attente dans votre gestionnaire, donc si vous souhaitez exécuter quelque chose à la fin de celui-ci, le moyen le plus simple qui vient à l'esprit est de le placer comme Un autre Runnable code> sur la file d'attente:

mHandler.post(new Runnable() {
    @Override
    public void run() {
        mHandler.postDelayed(r, DELAY);
    }
});


2 commentaires

Eh bien, cela ne fonctionnera pas, car les runnables doivent être exécutés immédiatement. L'ajout de nouveaux runnables est effectué par l'utilisateur et ne peut pas être prédit. Le délai est 5 ans, assez élevé.


Ahh, je pense que j'ai mal compris votre question. Donc, vous dites tous de votre exécutable s sont affichés avec le délai et que vous souhaitez à un moment donné, éliminez le délai pour le exécutable déjà affiché < / code> s?



0
votes

Vous avez besoin de quelques choses pour faire ce travail.

  1. Utilisez gestionnaire.SENDMessageDyedelayed (message) au lieu de gestionnaire.posdelayed et attribue un sens significatif quelle valeur sur votre Code>
  2. Lorsque vous devez affleurer la file d'attente, vérifiez si quelque chose est déjà mis en file d'attente avec gestionnaire.hasmesages (int) . S'il y a quelque chose, vous pouvez le supprimer avec handler.removemessages et l'exécuter vous-même.

0 commentaires

3
votes

Dans un tableau, gardez une trace des runnables qui vont être appelés, alors, si vous voulez qu'ils soient appelés, annulez le postdelayed et appelez directement les runnables, pour les déclencher, appelez simplement le Exécuter () Méthode de la runnable. Exemple de code:

// Declaring the Handler and the Array that is going to track Runnables going to be tracked.
final mHandler = new Handler();  
final List<Runnable> callStack = new ArrayList<Runnable>();

// Method to remove a runnable from the track Array.
public void removePostDelayed(Runnable run) {
    callStack.remove(run);
}

// Method that we use in exchange of mHandler.postDelayed()
public void myPostDelayed(Runnable run, int delay) {
    // I remove callbacks because I don't know if can be called 2 times.
    mHandler.removeCallbacks(run);

    // We remove the Runnable from the tracking Array just in case we are going to add a Runnable that has not been called yet.
    removePostDelayed(run);

    // We add the runnable to the tracking Array and then use postDelayed()
    callStack.add(run);
    mHandler.postDelayed(run, delay);
}

// This is the Runnable. IMPORTANT: Remember to remove the Runnable from the tracking Array when the Runnable has been called.
Runnable myRunnable = new Runnable() {
    @Override
    public void run() {
        // Do some fancy stuff and remove from the tracking Array.
        removePostDelayed(this);
    }
}

// Method to execute all Runnables
public void callAllStack() {
    // We create a copy of the tracking Array because if you modify the Array while you are iterating through it, will return an Exception.
    List<Runnable> callStackCopy = new ArrayList<Runnable>();

    // here we copy the array and remove all callbacks, so they are not called by the Handler.
    for (Runnable runnable : callStack) {
        callStackCopy.add(runnable);
        mHandler.removeCallbacks(runnable);
    }

    // Then we call all the Runnables from the second Array
    for (Runnable runnable : callStackCopy) {
        runnable.run();
    }

    // And clear the tracking Array because the Handler has no more Runnables to call (This is redundant because supposedly each run() call removes himself from the tracking Array, but well... just in case we forgot something).
    callStack.clear();
}

// Example of postDelaying a Runnable while tracking if has been fired.
myPostDelayed(myRunnable, 1000)

// Example of firing all Runnables.
callAllStack();


0 commentaires