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 :

Enchainement de N AsyncTask


Sujet :

Android

  1. #1
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2011
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2011
    Messages : 50
    Points : 43
    Points
    43
    Par défaut Enchainement de N AsyncTask
    Bonjour,
    Je dois réaliser N appels successifs (par exemple 10) à un module connecté Wifi. Il s'agit d'envoyer une commande et à attendre le résultat dont le temps de réponse est indéterminé dans un intervalle de temps maximal.
    J’ai donc créé une AsyncTask qui intègre une socket TCP client. Je déclenche une mesure par un événement bouton. Cà fonctionne.
    Maintenant comment faire pour lancer N mesures à partir d’un bouton, en ne bloquant pas tout le système.
    J’ai essayé d’attendre le status de l'AsyncTask FINISHED pour synchroniser la mesure suivante, mais ça bloque l’application.
    Mon code (f_serie_10() est la fonction déclenchée par le bouton) :
    Merci pour votre aide.
    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
     
    void f_serie_10() {
            int i,k=0;
            Tcp_com Tcp;
            Tcp = new Tcp_com();
            for (i=1;i<=10;i++) {
                status.setText("Essai: " + i);
                if (cible_free) Tcp.execute("TEST_COM");                        // lance mesure
                try {Thread.sleep(500);} catch (InterruptedException e) {};      // tempo 500 ms
                while (Tcp.getStatus() != AsyncTask.Status.FINISHED) {          // attend réponse cible
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) { }
                    k++;
                    status.setText("Tempo: " + k);
                }
                text_score.setText("Tir: "+i+" "+srec);        }
        }

  2. #2
    Expert confirmé
    Avatar de Hephaistos007
    Profil pro
    Enseignant Chercheur
    Inscrit en
    Décembre 2004
    Messages
    2 493
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 493
    Points : 4 166
    Points
    4 166
    Par défaut
    Je suppose que c'est Tcp_com() ton objet AsyncTask. Il est impossible d'invoquer 10 fois de suite execute() sur une même instance. Il faut creer 10 instances différentes.
    Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes --- devise SHADOKS

    Kit de survie Android : mon guide pour apprendre à programmer sur Android, mon tutoriel sur les web services et enfin l'outil en ligne pour vous faire gagner du temps - N'oubliez pas de consulter la FAQ Android

  3. #3
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2011
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2011
    Messages : 50
    Points : 43
    Points
    43
    Par défaut
    Merci pour la réponse.
    Ok pour le fait que l'on ne peut lancer N fois "execute" sur la même instance.
    Mon problème vient du fait que quand je fais une attente en testant le status de l'AsyncTask, elle est toujours en RUNNING.
    Je l'ai suivi avec le debugger, en mettant un point d'arrêt sur le return de la fonction "doInBackground".
    La fonction "onPostExecute" s'exécute correctement, mais une chose curieuse, lorsque je continue au debugger pas à pas , le programme entre de nouveau dans le run de la classe AsyncTask .
    Et le debugger m'affiche que l'AsyncTask est toujours RUNNING, ce qui explique le blocage du while.
    Est ce le fonctionnement normal ?

    Mon code:

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
     void f_serie_10() {
            if (!cible_free) return;
            Tcp_com tcp1;                                                     // mon AsyncTask
            tcp1=new Tcp_com();
            if (cible_free) tcp1.execute("TEST_COM");                         // lance mesure
            try {Thread.sleep(1000);} catch (InterruptedException e) {};      // tempo 1000 ms pour le lancement de tcp1
     
     
            while (tcp1.getStatus() != AsyncTask.Status.FINISHED)                 // attend réponse cible en interrogeant le status de tcp1
                {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) { }
                }
     
     
        }
     
        void tempo (int x) { try {Thread.sleep(x);} catch (InterruptedException e) {}}
        private static final int SERVER_PORT = 1336;
        private static final String IP_SERVER = "192.168.4.1";
     
    ////////////////////////////////////////////////////////////////////////////////////////////////////
                                                                    // Méthode TCP client
        private class Tcp_com extends AsyncTask<String, Void, String> {
     
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                status.setText("OnPreExecute !");
                cible_free = false;
            }
     
            @Override
            protected String doInBackground(String... params) {
                String sr = "Nothing;";
                String tcpMsg = params[0];
                try {
                    Socket s = new Socket(IP_SERVER, SERVER_PORT);
                    DataOutputStream outToServer = new DataOutputStream(s.getOutputStream());
                    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(s.getInputStream()));
     
                    tempo(500);                         // envoie commande
                    outToServer.writeBytes(tcpMsg);
     
                    tempo(500);                         // réception
                    sr = inFromServer.readLine();       // ligne vide
                    sr = inFromServer.readLine();       // le résultat
     
                    tempo(1000);                         //close connection
                    s.close();
                    inFromServer.close();
                    outToServer.close();
     
                }
                catch (UnknownHostException e) {}
                catch (IOException e) {}
     
                return "TCP2 " + sr;      // fin de doInBackground retourne la réponse du serveur
            }
     
            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);
                srec = result;
                status.setText(srec);
                String[] parts = srec.split(";");
                String part2 = parts[2];
                text_score.setText(part2);
                status.setText(srec);
                cible_free = true;
            }
     
        }

  4. #4
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 224
    Points
    20 224
    Par défaut
    Pas convaincu que l'asynctask soit adaptée dans ton cas.

    A mon avis un thread et un handler son plus adapté à ton problème :

    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
    Handler handler = new Handler() {
    	@Override
    	public void handleMessage(Message msg) {
    		TextView textView = (TextView)findViewById(R.id.textView);
    		myTextView.setText("Message recu du thread");
    	}
    };
     
    public void run() {
     
    	for (i=1;i<=10;i++) {
    		//Ton code
    		handler.sendEmptyMessage(0); // Notifie le handler
    	}
    };
     
    Thread mythread = new Thread(runnable);
    mythread.start();
    Pour la simplicité de l'exemple j'envoi un message vide mais on peut bien sur y ajouter des données , les envoyer à retardement , etc ...
    http://developer.android.com/referen...s/Handler.html
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2011
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2011
    Messages : 50
    Points : 43
    Points
    43
    Par défaut
    Ok, je vais potasser les threads handler et compagnie.

  6. #6
    Expert éminent

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Points : 9 149
    Points
    9 149
    Par défaut
    Même je peux pousser le bouchon un peu plus loin en de disant que les IntentService sont fait pour toi.

    http://developer.android.com/referen...ntService.html
    Responsable Android de Developpez.com (Twitter et Facebook)
    Besoin d"un article/tutoriel/cours sur Android, consulter la page cours
    N'hésitez pas à consulter la FAQ Android et à poser vos questions sur les forums d'entraide mobile d'Android.

  7. #7
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2011
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2011
    Messages : 50
    Points : 43
    Points
    43
    Par défaut
    Bonjour,
    J'ai mis en oeuvre la solution thread/handler. Cela fonctionne. J'ai pas le temps de voir les "IntentService". Dommage, ce sera pour la prochaine.
    Ci après mon code si cela peut aider. J'ai mis un bouton START pour démarrer N mesures, un CANCEL pour annuler, un PAUSE / RESUME, et un RESET pour que le serveur reprenne la main sur le process de mesure (cas d'une attente infinie).
    Je me suis inspiré du cours:
    http://mathias-seguy.developpez.com/...async_memleak/
    que je remercie et félicite au passage.
    Ne pas oublier de débloquer le wifi dans le manifest.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
        <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
     
    package com.example.jla.myapplication;
     
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Message;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ProgressBar;
    import android.os.Handler;
    import android.widget.TextView;
    import java.util.concurrent.atomic.AtomicBoolean;
    import java.net.*;
    import java.io.*;
     
    public class MainActivity extends Activity {
        //Thread background;
        ProgressBar bar;
        TextView text1;
        Button btnpause, btnresume, btnstart, btncancel, btnreset, btnquit;
        int count1 =0;
        private final String PROGRESS_BAR_INCREMENT="ProgreesBarIncrementId"; // La clef dans le bundle pour incrémenter la progressBar
        String tcpMsg ;
        String srec;
        int n_essai;
     
        Socket s;                                           // mise en place socket et IO
        DataOutputStream outToServer;
        BufferedReader inFromServer;
     
        Handler handler = new Handler() {					// Le Handler à charge de la communication entre la Thread
            // de background et celle de l'IHM
            @Override
            public void handleMessage(Message msg) {
                int progress=msg.getData().getInt(PROGRESS_BAR_INCREMENT);
     
                bar.incrementProgressBy(progress);				// Incrémenter la ProgressBar, on est bien dans la Thread
                count1 +=progress;                                //de l'IHM .On peut faire toute action qui met à jour l'IHM
                text1.setText(srec);
     
            }
        };
     
        AtomicBoolean isRunning = new AtomicBoolean(false);			// L'AtomicBoolean qui gère la destruction de la Thread de background
        AtomicBoolean isPausing = new AtomicBoolean(false);			// L'AtomicBoolean qui gère la mise en pause de la Thread de background
     
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            bar = (ProgressBar) findViewById(R.id.progress);		// Définition de la ProgressBar
            bar.setMax(200);
            text1 = (TextView) findViewById(R.id.text1);
            btnpause = (Button) findViewById(R.id.btnpause);
            btnresume = (Button) findViewById(R.id.btnresume);
            btnstart = (Button) findViewById(R.id.btnstart);
            btncancel = (Button) findViewById(R.id.btncancel);
            btnreset = (Button) findViewById(R.id.btnreset);
            btnquit = (Button) findViewById(R.id.btnquit);
     
            // action bouton start
            btnstart.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (isRunning.get()) return;                // sort si le therad est en cours
                    tcpMsg = "TEST_COM_1";                      // positionne type de commande serveur
                    srec="";                                    // variable réponse serveur
                    n_essai=10;                                 // nombre d'essai à enchainer
                    onStart_1();                                // lancement du thread
                }
            });
     
            // action bouton cancel
            btncancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onStop();
                }
            });
     
            // action bouton pause
            btnpause.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                   onPause();
                }
            });
     
            // action bouton resume
            btnresume.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onResume();
                }
            });
     
            // action bouton reset- Envoi la commande RESET au serveur
            // cette procèdure est nécessaire lorsque le process de mesure est en attente infinie
            // la commande RESET supprime la boucle infinie et le serveur envoie une réponse au client
            // ce qui permet de débloquer le thread Mesure_N.
            btnreset.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!isRunning.get()) return;                   // le reset n'est effectif que si on est en mesure
                    Thread Reset_C = new Thread(new Runnable() {         // Définition de la Thread de reset
                        public void run() {
                            try {
                                outToServer.writeBytes("RESET");     // envoie commande (suppose que la socket et le DataOutputStream existe
                            } catch (UnknownHostException e) {
                                srec = e.toString();
                            } catch (IOException e) {
                                srec = e.toString();
                            }
                        }
                    });
                    isRunning.set(false);                                      //Re-Initialisation des AtomicBooleans
                    isPausing.set(false);
                    Reset_C.start();
     
                }
            });
     
            // action bouton quit
            btnquit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finish();
                }
            });
        }
     
        void tempo (int x) { try {Thread.sleep(x);} catch (InterruptedException e) {}}
        private static final int SERVER_PORT = 1336;
        private static final String IP_SERVER = "192.168.4.1";
     
        public void onStart_1() {						            // Méthode du cycle de vie de l'activité (lancement)
           // super.onStart();
            bar.setProgress(0);						                // initialisation de la ProgressBar
            Thread Mesure_N = new Thread(new Runnable() {         // Définition de la Thread
                Bundle messageBundle = new Bundle();                // Le Bundle qui porte les données du Message et sera transmis au Handler
                Message myMessage;                                  // Le message échangé entre la Thread et le Handle
                String sr;
     
                public void run() {
     
                    try {                                                // mise en place socket et IO
                        s = new Socket(IP_SERVER, SERVER_PORT);
                        outToServer = new DataOutputStream(s.getOutputStream());
                        inFromServer = new BufferedReader(new InputStreamReader(s.getInputStream()));
                    } catch (UnknownHostException e) {
                        srec = e.toString(); return;
                    } catch (IOException e) {
                        srec = e.toString(); return;
                    }
     
                    tempo(500);
     
                    try {
                        for (int i = 1; i <=n_essai  && isRunning.get() ; i++) {        // si isRunning true fin de boucle et de thread
                            while (isPausing.get() && (isRunning.get())) tempo(2000);   // traiter la pause en soulageant le CPU
     
                            try {
                                outToServer.writeBytes(tcpMsg);     // envoie commande
                                tempo(500);                         // réception
                                sr = inFromServer.readLine();       // ligne vide
                                srec = inFromServer.readLine();     // le résultat
                            } catch (UnknownHostException e) {
                                srec = e.toString();
                            } catch (IOException e) {
                                srec = e.toString();
                            }
     
                            tempo(100);
                            srec+="Essai:  "+i;
     
                            myMessage = handler.obtainMessage();            // Envoyer le message au Handler (la méthod handler.obtainMessage est plus efficace
                                                                            // que créer un message à partir de rien, optimisation du pool de message du Handler)
                                                                            //Instanciation du message (la bonne méthode):
                            messageBundle.putInt(PROGRESS_BAR_INCREMENT, 1); //Ajouter des données à transmettre au Handler via le Bundle
                            myMessage.setData(messageBundle);                  //Ajouter le Bundle au message
                            handler.sendMessage(myMessage);                 //Envoyer le message
     
                            tempo(1000);
                        }
                        s.close();
                        inFromServer.close();
                        outToServer.close();
                        isRunning.set(false);                                      //Re-Initialisation des AtomicBooleans
                        isPausing.set(false);
                    }
     
                    catch (Throwable t) {
                    }
                }
     
            });
     
            isRunning.set(true);                                            //Initialisation des AtomicBooleans
            isPausing.set(false);
            Mesure_N.start();
     
        }
     
                                                                            // Gestion du cycle de vie
        public void onStop() {                                              //Méthode appelée quand l'activité s'arrête
            super.onStop();
            isRunning.set(false);                                           //Mise-à-jour du booléen pour détruire la Thread de background
        }
     
     
        @Override
        protected void onPause() {
            super.onPause();
            isPausing.set(true);                                        // Mise-à-jour du booléen pour mettre en pause la Thread de background
        }
     
        @Override
        protected void onResume() {
            super.onResume();
            isPausing.set(false);                                       // Mise-à-jour du booléen pour relancer la Thread de background
        }
     
     
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Enchainement images et click
    Par TieumB dans le forum Windows
    Réponses: 3
    Dernier message: 02/02/2005, 10h55
  2. [ADO] enchainer deux TADOQuery
    Par cdlr27 dans le forum Bases de données
    Réponses: 1
    Dernier message: 30/12/2004, 10h36
  3. Enchainer des fonctions dans un onclick d'un bouton
    Par jpg dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 26/10/2004, 16h51
  4. [IHM] Enchainement des écrans
    Par CanardJM dans le forum Composants VCL
    Réponses: 6
    Dernier message: 22/06/2004, 16h01
  5. MSXML2, enchainer deux feuilles de Style
    Par burno dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 10/09/2003, 13h47

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