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 :

Exécuter plusieurs AsyncTask


Sujet :

Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 262
    Par défaut Exécuter plusieurs AsyncTask
    Bonjour,

    J'ai fait un petit exemple qui est très clair et qui fait la même erreur, si je resoud cet exemple je peux résoudre l'ereur dans mon programme.

    Voila le 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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    package com.example.ftpthread;
     
    import java.io.FileOutputStream;
     
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPFile;
    import org.apache.commons.net.ftp.FTPReply;
     
    import android.app.Activity;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.os.Environment;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
     
    public class MainActivity extends Activity {
     
        Connexion conx=null;
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
     
            Button bt= (Button) findViewById(R.id.button1);
            bt.setOnClickListener(new OnClickListener() {
     
                @Override
                public void onClick(View v) {
                    if (conx!=null){
                        Log.i("voila", "voila on est la 1");
                        conx.cancel(true);
                        conx=new Connexion();
                        conx.execute("73383_20130426_Tessenderlo_VBR_3.pdf");
     
                    }
     
                    conx=new Connexion();
                    conx.execute("73383_20130426_Tessenderlo_VBR_3.pdf");
                }
            });
        }
     
        class Connexion extends AsyncTask<String, String, String> {
            FTPClient mFTPClient;
            @Override
            protected String doInBackground(String... params) {
                Log.i("voila", "voila on est la 2");
                 String chaine = params[0];
                     try {
                            mFTPClient = new FTPClient();
                            mFTPClient.connect("site", 21);
                            Log.i("voila", "voila on est la 4");
                            if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
                                boolean status = mFTPClient.login("user", "pass");
                                mFTPClient.enterLocalPassiveMode();
                                ftpDownload("/fromCIS/" +chaine ,
                                        Environment.getExternalStorageDirectory()
                                                + "/Fromcis/" + chaine);
                                  mFTPClient.logout();  
                                  mFTPClient.disconnect();
     
                            }
                        } catch (Exception e) {
     
                        }
                     return "zaki";    
            }
     
            @Override
            protected void onPostExecute(String result) {
                // TODO Auto-generated method stub
                super.onPostExecute(result);
                Log.i("voila", "voila on est la onpost");
                conx=null;
     
            }
     
            public boolean ftpDownload(String srcFilePath, String desFilePath) {
                boolean status = false;
                try {
                    FileOutputStream desFileStream = new FileOutputStream(
                            desFilePath);
                    ;
                    status = mFTPClient.retrieveFile(srcFilePath, desFileStream);
                    desFileStream.close();
     
                    return status;
                } catch (Exception e) {
                    Log.d(e.getCause() + "", "download failed");
                }
     
                return status;
            }
        }
    }
    C'est un exemple de téléchargement de fichier PDF depuis un serveur FTP. Le problème est que quand j'appuie plusieurs fois dans le AsyncTask, ça fonctionne pour les premiers clics mais ensuite ça ne fonctionne plus.

    Dans le log ça m'affiche :
    Log.i("voila", "voila on est la 1")
    donc, la tache est occupée mais normalement d'après le code que j'ai mis, je dois l'interrompre et exécuter une autre tâche. Malheureusement, elle ne fait pas ça et j'ignore ce qui se passe.

    D'après ce que j'ai lu c'est que AsyncTask.cancel ne permet pas de terminer la tâche.

    Quelqu'un saurait-il m'indiquer d'où peut venir le problème ?

    Merci d'avance pour votre aide.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    757
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 757
    Par défaut
    En effet, la méthode cancel() d'un AsyncTask ne l'arrête pas directement.
    En fait, cela va ajouter un flag interne à l'AsyncTask exprimant que l'AsyncTask doit s'arrêter. Mais c'est au développeur de le faire. Cela n'est pas automatique.

    Pour arrêter correctement un AsyncTask, il faut vérifier fréquemment la valeur de isCancelled() dans la méthode doInBackground. Si cette valeur est égale à false, alors tu peux arrêter le travail, sinon tu peux continuer.

  3. #3
    Expert confirmé

    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
    Billets dans le blog
    3
    Par défaut
    Ou sinon utiliser cancel(true), et bien être sur de gérer correctement les "InterruptedException" qui se produiront alors dans le doInBackground....

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 262
    Par défaut
    tout d'abord merci pour vos réponses.

    le problème d’après plusieurs test c'est que le thread se bloque dans la méthode de téléchargement dans le code : c'est cette méthode:

    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
       public boolean ftpDownload(String srcFilePath, String desFilePath) {
                boolean status = false;
                try {
                    FileOutputStream desFileStream = new FileOutputStream(
                            desFilePath);
                    ;
                    status = mFTPClient.retrieveFile(srcFilePath, desFileStream);
                    desFileStream.close();
     
                    return status;
                } catch (Exception e) {
                    Log.d(e.getCause() + "", "download failed");
                }
     
                return status;
            }
        }
    j'ai fait un test : j'ai essayé de télécharger le mémé fichier plusieurs fois, les premiers téléchargement le thread fonctionnait très bien, mais une fois il s'est arrête et j'ai vu dans éclipse dans la partie DDMS que le fichier ne s'est pas telechargé complétement, juste une partie, et il reste bloqué dans cette partie.

    et quand je lance un nouveau thread , il fait rien .

    j'ai essayé ce que vous m'avez dit mais aucune solution.a quoi sert de tester iscanceled dans le doinbackround sachant que je fait le travail une seul fois , mais j''ai pas une boucle.

    le problème d’après ce que j'ai vu c'est que le thread reste bloqué dans la méthode de téléchargement , est ce qu'il y a moyen de sortir de cette méthode , ou moyen de tuer le thread . j'ai vu dans un exemple l'utilisation d'une liste de tache et a chaque fois quand veut tuer un thread on le supprime de la liste mais je crois que c'est le même truc si on met la tache dans une variable.

    Merci d'avance pour votre aide.

  5. #5
    Expert confirmé

    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
    Billets dans le blog
    3
    Par défaut
    Non mais cancel(true) il fait rien ? (le "true" est important hein !)

    Il devrait envoyer un "interrupt" au thread qui execute la tâche, et donc interrompre immédiatement tout "wait" avec un InterruptedException.

  6. #6
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2013
    Messages : 20
    Par défaut
    Bonjour,

    Pour régler le problème :

    Déclarer Le AsyncTask dans un nouveau fichier .java
    Ajouter un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private boolean ThreadLance = false;
    Dans le PostExecute :
    Définir un getter pour ce boolean

    Dans la mainActivity
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (!conx.getThreadLance) conx.execute();
    else 
    {
    conx = null;
    conx = new connexion()
    conx.execute();
    }
    Cela provient du fait qu'un Thread ne peut être lancé qu'une fois. Donc si il n'est pas recréer il ne se ne lance plus et renvoie en général une erreur.

  7. #7
    Expert confirmé

    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
    Billets dans le blog
    3
    Par défaut
    Oui enfin... entre stocker l'AsyncTask ou stocker un boolean pour savoir si il est lancé, je vois pas la différence:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    myTask = ....;
    myTask.execute();
     
    if (myTask != null) 
        myTask.cancel(true);
    Mais bon... là en l'occurence, on sait si il est lancé ou non, on veut jute l'arrêter !
    (et le boolean ne permettra jamais de le stopper).

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 28/11/2007, 15h44
  2. Réponses: 5
    Dernier message: 15/03/2007, 11h21
  3. Exécuter plusieurs commandes bat
    Par n@n¤u dans le forum Langage
    Réponses: 4
    Dernier message: 31/08/2006, 15h23
  4. Sous-requête excutée plusieurs fois dans une requête
    Par sheridan31 dans le forum Oracle
    Réponses: 8
    Dernier message: 03/07/2006, 16h18
  5. [2k] Exécuter plusieurs fichiers SQL
    Par drinkmilk dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 28/06/2006, 14h03

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