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 :

Thread et résultat fonction


Sujet :

Android

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    206
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 206
    Points : 87
    Points
    87
    Par défaut Thread et résultat fonction
    Bonjour,

    Voici mon souci:
    Dans mon activité, j'ai 2 fonctions qui contiennent chacune une thread.
    1ere, va chercher des données dans ma BDD et affiche le résultat dans un spinner.
    La 2eme récupère l'index du spinner et affiche un tableau de valeur.

    Les 2 fonctions fonctionnent seules mais pas ensemble.

    Mon programme execute mes fonctions mais n'attend pas le code retour de mon thread.
    J'ai réussi à régler ce problème sur la 1ere fonctions mais lorsque je fais la meme chose sur la 2eme fonction et que je teste, mon affichage est tout noir...

    Voici 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
    76
    77
    78
    79
    80
    81
     
    ListeChampionnat();
    while(EtatListeChampionnat=="123")//fonctionne
    {
    	//On attend la fin de la fonction ChargeSpinner
    }
     
    if (EtatListeChampionnat == "NO_ERREUR") 
    {
    	msg = mHandler.obtainMessage(MSG_CNF,"Chargement Spinner OK");
    	mHandler.sendMessage(msg);
     
    	Spinner Spinner2 = (Spinner) findViewById (R.id.spinner); 
    	//Création d'un adaptateur pour spinner
    	ArrayAdapter DataAdapter = new ArrayAdapter (getApplicationContext(), android.R.layout.simple_spinner_item, NomChampionnat);
    	DataAdapter.setDropDownViewResource (android.R.layout.simple_spinner_dropdown_item);
    	Spinner2.setAdapter(DataAdapter);
     
    	String resultat = Calendrier();
     
    	while(EtatChargeCalendrier=="123")//affiche un écran noir
    	{
    		//On attend la fin de la fonction Calendrier
    	}
     
    	if (resultat == "NO_ERREUR") 
    	{
    		msg = mHandler.obtainMessage(MSG_CNF,"Chargement Calendrier OK");
    		mHandler.sendMessage(msg);
    	}
    }
    ...
    public void /*String*/ ListeChampionnat(){
    mProgressDialog = ProgressDialog.show(this, "Veuillez patienter","Chargement en cours...", true);
     
    new Thread((new Runnable() {
    	//@Override
    	public void run() {
    		Message msg = null;
    		String progressBarData = "Chargement en cours...";
    		progressBarData = "Chargement en cours...";
    		msg = mHandler.obtainMessage(MSG_IND,(Object) progressBarData);
    		mHandler.sendMessage(msg);
    		ChargeSpinner();
    	}
     
    	public void ChargeSpinner() {
    	...
    	EtatListeChampionnat="NO_ERREUR";
    	}
    	})).start();
    }
     
    public String Calendrier()
    {
    	Etat="123";
    	mProgressDialog = ProgressDialog.show(this, "Veuillez patienter","Connexion en cours...", true);
    	final Thread t1 = new Thread(){
    	public void run() {
    		Message msg = null;
    		String progressBarData = "Chargement en cours...";
    		progressBarData = "Chargement en cours...";
    		msg = mHandler.obtainMessage(MSG_IND,(Object) progressBarData);
    		mHandler.sendMessage(msg);
    		ChargeTableau();
     
    	}
     
    	public void ChargeTableau() {
    	...
    	EtatChargeCalendrier="NO_ERREUR";
    	}
     
    	};
    	t1.start();
    	try {
    		t1.join();
    	} catch (InterruptedException e) {
    		e.printStackTrace();
    	}
    }
    Comment dois-je faire?

    Merci pour votre aide

  2. #2
    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
    Ne pas utiliser de thread ?

    Je plaisante, mais à moitié seulement. Ce qui met la puce à l'oreille est l'appel à la fonction "join()".
    Et surtout l'horreur de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while(EtatListeChampionnat=="123")//fonctionne
    {
    	//On attend la fin de la fonction ChargeSpinner
    }
    Ce code tourne en permanence tant que la fonction ChargeSpinner n'est pas revenue... Non seulement cela va bouffer du temps CPU inutile, mais en plus l’intérêt d'un "thread" dans ChargeSpinner disparaît complètement puisqu'on attend SA FIN !

    Donc plusieurs conseils:
    1. Respecter les normes de nommage Java... Ces normes existent pour des raisons de lisibilité du code, autant les conserver de partout, en particulier les identifiants sont tous en "CamelCase" ou "camelCase", et seuls les types (class, enum, interface) ont leur première lettre en majuscule... Jamais d'utilisation du '_'. Seule exception à ces deux règles les constantes (static final) qui sont entièrement en majuscules avec des '_' pour séparer les mots.
    Le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Spinner Spinner2 = (Spinner) findViewById (R.id.spinner);
    n'en deviendra que plus lisible pour un programmeur Java...

    2. Si on n'a pas une bonne connaissance de la programmation concurrentielle éviter d'utiliser les Thread. Surtout quand il doit y avoir une synchronisation entre ceux-ci. Android propose plein d'outils évitant de manipuler ceux-ci et, merveille, proposent aussi des moyens faciles de synchronisation avec le thread principal (celui de l'interface): AsyncTask, Loader, ... Le thread principal pouvant alors service de "point" d'attache pour les divers "codes parallèles".

    En l’occurrence, simplement dans l'activité
    Une tâche "ListeChampionnat", qui sera démarrée dès l'entrée dans l'activité...
    Une tâche "ChargeTableau", qui sera démarrée à chaque sélection du spinner...(ce qui sera aussi le cas après que celui-ci ait été initialisé, donc à la fin de ListeChampionnat).

    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
     
    class MyActivity extends Activity implements OnItemSelectedListener {
         ...
         Spinner spinner;
         TextView progress;
     
         // Remplacer "Championnat" par le type de donnée correspondant
         // en général, une classe "Championnat" fera l'affaire.
         class ListeChampionnat extends AsyncTask<Void,Void,ArrayList<Championnat>> {
             @Override
             protected void onPreExecute()
             {
                  MyActivity.this.progress.setText("Chargement en cours..."); // <= R.string. plutôt
             }
     
             @Override
             protected void onPostExecute(ArrayList<Championnat> liste) {
                 // la tâche est finie, on crée l'adapter qui va bien, et on met à jour le spinner.
                 ArrayAdapter<Championnat> adapter = new ArrayAdapter<Championnat>(...., liste);
                 MyActivity.this.spinner.setAdapter(adapter);
             }
     
             @Override
             protected ArrayList<Championnat> doInBackground(Void ... params) {
                 // le vrai travail de la tâche est ici, et sera exécuté "en tâche de fond".
                 ArrayList<Championnat> ret = new ArrayList<Championnat>();
                 ...
                 remplissage de la liste
                 ...
                 return ret;
             }
         }
     
         // remplacer ???? par le type de données voulues en sortie.
         class ChargeTableau extends AsyncTask<Championnat,Void,????> {
              @Override
              protected ???? doInBackground(Championnat ... values) {
                  // le travail de lecture des données du championnat...
                  ???? ret;
                  // on n'aura qu'un seul paramètre, c'est donc le premier qu'on utilise.
                  Championnat c = values[0];
     
                  ... lecture du tableau (????) pour le championnat...
     
                  return ret;
              }
     
              protected void onPreExecute() {
                  MyActivity.this.progress.setText("Chargement championnat...");
              }
     
              protected void onPostExecute(???? data) {
                  // on a finit de lire les données, il est temps de les afficher...
                  MyActivity.this.displayTableau(data);
                  MyActivity.this.progress.setText("");
              }
         }
     
         @Override
         public void onCreate(Bundle saved)
         {
              super.onCreate(saved);
              setContentView(R.layout.xxxxxx);
     
              this.spinner = (Spinner) findViewById(R.id.spinner);
              this.progress = (TextVew) findViewById(R.id.progressBar);
     
              this.spinner.setOnItemSelectedListener(this);
     
              // quand on commence l'activité on remplit la liste de championnats.
              new ListeChampionnat().execute();
         }
     
         public void onItemSelected(AdapterView<?> parent, View view,  int pos, long id) {
              // quand un championnat est selectionné, on peut le récupérer directement depuis l'adapter.
              Championnat c = (Championnat) parent.getAdapter().getItem(pos);
              // et demander à l'afficher (à noter qu'on découple le fait que la fonction "displayChampionnat" utilise une tâche, ce n'est pas le problème de cette fonction.
              displayChampionnat(c);
         }
     
         public void onNothingSelected(AdapterView<?> parent) {
              // quand rien n'est selectionné, on n'affiche rien...
              displayTableau(null);
         }
     
         public void displayChampionnat(Championnat c)
         {
             // afficher un championnat demander l'execution d'une tâche
              new ChargeTableau().execute(c);
         }
     
         public void displayTableau(???? data)
         {
              // l'affichage des données du championnat.
              if (data == null) {
                  // on efface tout
              } else {
                  // on affiche tout
              }
         }
    }
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    206
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 206
    Points : 87
    Points
    87
    Par défaut
    Bonjour nicroman et merci pour ta réponse.

    Je pense avoir compris le fonctionnement et je me base sur ton code pour le mettre en œuvre.

    La classe "ListeChampionnat" fonctionne bien.
    En revanche je n'ai pas pu tester la classe "ChargeTableau" car la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public void onItemSelected(AdapterView<?> parent, View view,  int pos, long id)
    ne fonctionne pas et je ne sais pas pourquoi...

    Je ne rentre jamais dans cette fonction.

    Peux-tu m'aider stp?

    Merci d'avance

  4. #4
    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
    Salut,

    Peux tu poster ton code ? Vu que l'on a rien j'aimerais parier sur un mauvais import dans ta classe ? Est ce que j'ai juste ?
    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.

Discussions similaires

  1. Réponses: 2
    Dernier message: 07/08/2008, 21h21
  2. Afficher résultat fonction
    Par jcaspar dans le forum Langage
    Réponses: 4
    Dernier message: 04/09/2007, 10h22
  3. Réponses: 9
    Dernier message: 24/08/2007, 12h37
  4. Requete dans un Thread -> double résultat
    Par Invité dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 14/06/2006, 14h37
  5. Thread avec une fonction membre d'une classe
    Par SteelBox dans le forum Windows
    Réponses: 6
    Dernier message: 01/03/2004, 01h15

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