IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

Désactiver un Listener


Sujet :

Android

  1. #1
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut Désactiver un Listener
    Bonjour à toutes et à tous,

    Dans l'application pour GPS que j'ai créée et qui fonctionnait très bien avec la version 4.0.4 d'android, j'ai tout un tas de problèmes suite à la mise à jour en 4.1.2. Au-delà du problème de mémoire (voir mon poste à ce sujet), il me semble que le comportement des Listener est différent.

    L'exemple est le suivant : en version 4.0.4, lorsque j'appuyais sur l'écran pour déplacer une image, celle-ci se déplaçait uniquement tant que mon doigt restait appuyé sur l'écran. Ce déplacement apparaissait saccadé quand, lors du déplacement, le système devait charger une nouvelle image.

    Avec la version 4.1.2, j'ai l'impression que le système mémorise tous les appels au Listener dans une pile et continue à les restituer jusqu'à ce que le pile soit vide, même si j'ai cessé d'appuyer sur l'écran.
    Y a-t-il un moyen de pallier ce problème ?

    Je pense à soit une option de programmation ou soit à la possibilité de désactiver temporairement l'appel au Listener.

    Merci pour votre aide.

    Pierre

  2. #2
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Le phénomène de "dépilage" est vraiment très pénible, la carte continue de bouger au gré des infos empilées, ce qui peut prendre plusieurs secondes, à un rythme très aléatoire et qui n'a plus aucun rapport avec les mouvements qu'on veut faire.

    Par ailleurs, je ne peux pas mettre dans un thread le chargement de chaque nouvelle carte au moment où j'en ai besoin car c'est ce chargement qui fait que les données vont être valides ou non. Dit autrement, si la carte se charge en temps masqué (c'est-à-dire avec délais), l'application plante.

    Que l'avancement de la carte se bloque au moment d'un changement de carte ne me gène pas en soit même. Ce que je voudrais, c'est bloquer l'empilage d'infos de déplacement (dû au glisser sur l'écran) tant que la carte n'est pas chargée.

    Le (pseudo) code est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    affCarte.setOnTouchListener(new View.OnTouchListener() { // Déplacement de la carte par touché de l'écran
    @Override
      public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        ...
        if (action == MotionEvent.ACTION_DOWN) {
          xd = event.getX();
          yd = event.getY();
     					}
        if (action == MotionEvent.ACTION_MOVE) {
          Calcul du déplacement;
          Si en bord de carte {
            charger celle qui vient : ça, ça prend entre 0.2 et 0.5 secondes et pendant ce
            temps les infos de déplacement s'empilent;
          }
          invalidate(); // rafraichissement de l'image
        }
        return false;
      }
    });
    Que faire pour éviter l'empilement ?

    Merci de votre aide.

    Pierre

  3. #3
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Ben moi c'est ça qui me gène:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     Si en bord de carte {
            charger celle qui vient : ça, ça prend entre 0.2 et 0.5 secondes et pendant ce
            temps les infos de déplacement s'empilent;
          }
    Si ça prend ce temps là, il ne faut surtout pas le faire ici... en particulier dans un onTouch ou j'hésiterai grandement à dépasser le centième de seconde...

    Gérer le truc dans un thread à part... un service... ou je ne sais quoi. Mais en "cancellable" (le cas ou le doigt fait tout l'écran à gauche, puis tout l'écran à droite).

    Autre solution: avoir une version "light" à afficher tout de suite, et commencer un refresh asynchrone lors du touchUp....
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  4. #4
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Merci nicroman pour ces propositions.

    J'ai essayé de mettre ce chargement dans un Thread, mais ça plante. Peut-être que je m'y suis mal pris. Pour autant, si je n'attends pas la fin du chargement de la nouvelle carte, la procédure d'affichage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cnv.drawBitmap(FCH.bitmap, mxMap, paint); //Dessin du bitmap de la carte sélectionnée
    va se baser sur quelque chose qui n'existe pas, et ça va planter !

    Je vais réessayer et donner le code que j'obtiens etvous demanderai où ça ne va pas.

    Merci de votre aide.

    Pierre

  5. #5
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Je vais essayer de préciser ce qu'il se passe avec mon code original (voir post #2) :

    Si je ne suis pas en bordure de carte, je n'ai pas de nouvelle carte à charger, le calcul est rapide et les déplacements à l'écran se font de manière fluide en suivant les mouvements du doigt.

    Si je suis en bordure de carte, alors je charge une nouvelle carte, ce qui prend du temps. Alors que je continue à déplacer mon doigt sur l'écran, l'affichage se bloque (sur le bord de carte) pendant que le fichier se charge, puis il se débloque, comme pour rattraper son retard et dès lors, les mouvements deviennent un peu erratiques, par paquets temporels parfois séparés de quelques dixièmes de seconde à près d'une seconde. Tout cela bien que mon doigt a cessé d'appuyer sur l'écran ou bien qu'il soit resté appuyé mais sans bouger.

    J'ai installé une tâche asynchrone comme le montre le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    private class ChargeMapTask extends AsyncTask<Float, Void, Void> {
      @Override
      protected Void doInBackground(Float... params) {
        deplaceAff(params[0], params[1]); // même procédure que dans le code original
        return null;
      }
      @Override
      protected void onPostExecute(Void result) {
        monImg.invalidate();
      }
    }	
     
    affCarte.setOnTouchListener(new View.OnTouchListener() { // Déplacement de la carte par touché de l'écran
    @Override
      public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        ...
        if (action == MotionEvent.ACTION_DOWN) {
          xd = event.getX();
          yd = event.getY();
     					}
        if (action == MotionEvent.ACTION_MOVE) {
          new ChargeMapTask().execute(event.getX(), event.getY()); // appel de la tâche asynchrone
        }
        return false;
      }
    });
    Résultats :

    C'est la pagaille totale, que je charge ou pas une carte. Le déplacement de l'affichage parait décorrélé des mouvements du doigt sur l'écran et de toutes façons, les mouvements continuent après que j'ai cessé d'appuyer ou que je reste appuyé mais sans bouger.

    Bon, je suppose que je n'ai rien compris aux tâches asynchrones.

    Ce que je voudrais : que tant que la nouvelle carte n'est pas chargée, qu'il n'y ait pas de rafraichissement de l'écran (et qu'il n'y en ait pas en stock dans une pile comme cela semble être).

    Je patauge ... merci de votre aide.

    Pierre

  6. #6
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    Par défaut
    Après divers essais, il ne me semble pas souhaitable de mettre la tâche de chargement de carte dans un AsyncTask car, dès qu'il y a un petit temps de latence, les ordres de déplacements arrivent ... quand ils peuvent et on a l'impression que les déplacements à l'écran n'ont plus aucun rapport avec ceux du doigt.

    Dans mon code sans AsyncTask, j'ai placé des compteurs en divers endroits, notamment un dans la procédure onTouch. J'ai constaté la chose suivante : quand j'arrive à un changement de carte, l'affichage se bloque ainsi que mon compteur. Je cesse d'agir (relachement du touché ou touché sans mouvement), et tout d'un coup, le compteur se remet à croître en même temps que le déplacement reprend. Cela peut s'étaler sur plusieurs secondes, tout dépend de la quantité de mouvements que j'avais précédemment faite.

    Cela veut dire que les touchés d'écran, à un niveau "supérieur", on été stockés sur une pile et, dès que la tâche de chargement était finie, ils se sont dépilés en appelant la procédure onTouch de mon programme.

    D'où l'idée suivante : est-il possible d'intercepter les évènements de touché d'écran à leur plus haut niveau avant qu'ils soient dispatchés vers les demandeurs (Je sais, pour l'avoir fait, que cela se fait sous Windows, quand est-il pour Android ?).

    Merci pour votre aide.

    Pierre

Discussions similaires

  1. Désactiver un listener pendant une animation
    Par Shuret dans le forum jQuery
    Réponses: 1
    Dernier message: 07/04/2010, 01h26
  2. désactiver les listener
    Par slim_java dans le forum 2D
    Réponses: 5
    Dernier message: 01/09/2009, 15h56
  3. Réponses: 7
    Dernier message: 12/06/2007, 11h36
  4. Désactiver les touches F1, F2, F3, F4, F5 dans IE
    Par ZiZouJH dans le forum Flash
    Réponses: 7
    Dernier message: 17/02/2003, 09h59
  5. Réponses: 8
    Dernier message: 17/05/2002, 09h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo