Aller au contenu

Comment faire fonctionner correctement l'affichage du préload en éxécutant 3 classes Asynctask consécutivement?


didier51

Recommended Posts

Bonjour à tout les développeurs android,

y aurait-il des personnes de la communauté qui pourraient m'aider?

Je développe actuellement une application Android et j'ai un petit problème d'affichage.

Comment faire fonctionner correctement l'affichage du préload en éxécutant 3 classes Asynctask consécutivement?

préload  : affichage d'une petite roue qui tourne pendant le téléchargement pour faire patienter l'utilisateur.

 

Problème d'affichage :

--------------------

1 - En travaillant avec une seul classe Asynctask, l'affichage du preload s'affiche correctement en début de traitement et disparait à la fin du traitement.

2 - En travaillant avec plusieurs classes Asynctask, l'attente des réponses aux requetes des classes Asynctask fait que le préload s'affiche à la fin du traitement.

 

Résultat attendu de mon application :

-----------------------------------

Pendant le téléchargement de différentes requetes sur un serveur, afficher le préload.

A la fin du traitement, faire disparaitre le préload et afficher le résultat.

 

Le traitement s'éffectue en 3 étapes :

------------------------------------

 1 - Télécharger l'identifiant client (indispensable pour pouvoir télécharger les identifiants des articles).

 2 - Télécharger les identifiants des articles (indispensable pour pouvoir télécharger les cotations des articles).

 3 - Télécharger les cotations des articles (afin de les afficher).

 

Données du problème :

-------------------

 1 - La classe Asynctask_1 télécharge l'identifiant_client.

 2 - La classe Asynctask_2 télécharge les identifiants_des_articles.

 3 - La classe Asynctask_3 télécharge les cotisations_des_articles.

 

Chronologie du programme :

------------------------

- 1 - La classe mere éxécute la classes Asynctask_1 et attent la réponse de celle ci (identifiant_client) pour pouvoir éxécuter la classes Asynctask_2.

- 2 - La classe mere éxécute la classes Asynctask_2 et attent la réponse de celle ci (identifiants_des_articles) pour pouvoir éxécuter la classes Asynctask_3.

- 3 - La classe mere éxécute la classes Asynctask_3 et attent la réponse de celle ci (cotations des articles) pour pouvoir afficher le résultat.

- 4 - La classe mere affiche le résultat (les cotations des articles).

 

Problème :

--------

Il y a un temps d'attente entre les différentes requètes des classes Asynctask et la réponse.

A partir de la 2° classe asynctask, l'attende du résultat de la requete fait que l'affichage du préload s'affiche à la fin du traitement alors qu'il devrait apparaître en début.

 

Résultat de l'application :

-------------------------

L'application affiche bien les cotations des articles mais le préload s'affiche à la fin du traitement.

 

Merci à tous ceux et celles qui pouraient m'aider à trouver une solution à ce petit probleme d'affichage.

Lien vers le commentaire
Partager sur d’autres sites

Bonjour,

 

Le principe d'affichage d'un message d'attente dans le cas d'un traitement asynchrone est normalement relativement simple: tu affiches le message d'attente avant de lancer le traitement, et tu le supprimes lorsque le traitement est terminé (dans le cas d'AsyncTask, tu peux t'appuyer sur les méthodes onPreExecute/onPostExecute qui sont appelées avant exécution/après terminaison du thread géré par l'AsyncTask)

Dans ton cas, un petit point me chiffonne dans ton explication de la chronologie d'éxécution: quand tu parles de la classe mère (je suppose que c'est l'Activity) qui lance une AsyncTask et qui attend la réponse de celle-ci, qu'entends-tu par là ? est-ce à dire que tu effectues une attente active, depuis le thread principal, de la terminaison de l'AsyncTask ? si oui, ça veut dire que tu bloques l'IHM (et donc pas de mise à jour de l'interface) et que tes AsyncTasks ne servent pas à grand chose

Lien vers le commentaire
Partager sur d’autres sites

Merci Chpil pour ta réponse rapide. 
Voici le code de la méthode onCreate() qui je pense répondra à ta question et d'aider à mieux comprendre mes attentes.

 

Aussi, je te met la réponse à un autre forum de mon problème :

 

En faisant ceci :

Code Java :
retourIdClient = ObjetRetourIdClient.get();

Tu écris explicitement : "Je gèle le thread dans lequel je me trouve, jusqu'à avoir la réponse". Pour le coup, je me demande si cela fait lever l'exception NetworkOnMainThread sur les Android 3.0+, à tester tient.

Tu ne dois en aucun cas geler le thread graphique. Ce principe est véridique partout, quelle que soit la plate-forme, quel que soit le langage.
Les AsyncTask ont été créées comme sucre syntaxique, pour éviter une gestion lourde de hook courant.
La méthode doInBackground est invoquée dans un Thread en background, les méthodes onPostExecuteonPreExecute & onProgressUpdate sont invoquées dans le Thread graphique.
Ton interface ne doit jamais attendre la fin des tâches, mais uniquement réagir aux étapes de celles-ci.

Ici, le cas typique est la mise en place d'un pattern Observer.
Donc :

  • crée une Interface (par exemple : "TaskListener") possédant deux méthodes onSuccess et onFailure.
  • Rajoute une variable dans tes tâches : un type "TaskListener" (initialisée via constructeur, par exemple)
  • Dans le onPostExecute, invoque onSuccess OU onFailure de ton/tes listener (dépendant de comment ça s'est passé).
  • Fait en sorte que chaque classe appelante implémente cette interface et se transmettent aux tâches
  • Fait ce qu'il faut dans les classes implémentant l'interface "TaskListener" pour bien réagir suivant le onSuccess et onFailure

Actuellement, ton loader s'affiche en fin, et c'est tout à fait normal.
En traduisant le flux de ton application, ça donne ça :

  • je crée et affiche mon loader
  • je crée et lance ma première tâche
  • je gèle le thread graphique en attendant explicitement le retour (donc le loader... ne s'affiche pas)
  • je crée et lance X secondes tâches
  • je gèle le thread graphique à chaque fois en attendant explicitement le retour (donc le loader... ne s'affiche pas)
  • dans la boucle créant X seconds tâches, je crée mes troisième tâche
  • je gèle le thread graphique à chaque fois en attendant explicitement le retour (donc le loader ne s'affiche toujours pas)
  • j'ai fini, j'ai la main sur le thread graphique, j'affiche le loader
  • et je le dais disparaître de suite.

pour moi, c'est un peut flou.

Si tu peut m'éclairer un peut plus, j'en serai ravi.

 

Merci encore pour ton aide.

 

public class forum  extends ListActivity {
	
	public static String [] tableauIdArticle = new String[]{"idArticle1","idArticle2","idArticle3","idArticle4","idArticle5"};
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.cours); 
		
        	// Préload : Instance et Parametre progressDialog
		progressDialog = new ProgressDialog(this);
		
		//ProgressDialog progressDialog = null;
		// Préload : On ajoute  un message à   notre progress dialog
		progressDialog.setMessage("Chargement en cours");
		
		// Préload : Affichage le préload
		progressDialog.show();
		
		// 1 - Instancier la classe "Activite_Cours_Asynctask_Identifiant"
		// Telecharger le fichier xml contenant l'id client, le parcer et récupérer l'objet "id client"
		ObjetRetourIdClient = new Activite_Cours_Asynctask_Identifiant(this);
		ObjetRetourIdClient.execute();
		//-------------------------------------------------------------------
		
		// 1.1 - Retour du résultat du traitement Asynctask 
		//Cela permet de récuperer sans erreur "identifiantClientApres" dans la classe "Activite_Cours"
		try {
			retourIdClient = ObjetRetourIdClient.get();
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		} catch (ExecutionException e1) {
			e1.printStackTrace();
		}
		
        	int indexTableauObjet = 0;
	        int indexTableauCereals = 0;
	        int positionSwitch;

	        //Boucle balayant les 5 articles du tableau tableauIdArticle" afin de télécharger leurs cotations.
    		for(String iDArticle : tableauIdArticle){
    		
	    		// 2 - Instancier la classe Activite_Cours_Asynctask_identifiant_echeance()
	    		//------------------------------------------------------
		        // Telecharger le fichier xml contenant les 5 id échéances et les 5 échéances par produit,
    			// le parcer et récupérer le tableau contenant les 5 id_echeances et les 5 échéances"
	    		ObjetRetourIdentifiantEchance = new Activite_Cours_Asynctask_identifiant_echeance(this, iDArticle, retourIdClient);
     			ObjetRetourIdentifiantEchance.execute();
     			//------------------------------------------------------------------
    		
	    		// 2.1 - Retour du résultat du traitement Asynctask 
    			//Cela permet de récuperer sans erreur "tableauIdEcheancesRetour" dans la classe "Activite_Cours"
    		
    			try {
    				tableauIdEcheancesRetour = ObjetRetourIdentifiantEchance.get();
	    		} catch (InterruptedException e1) {
    				e1.printStackTrace();
    			} catch (ExecutionException e1) {
    				e1.printStackTrace();
	    		}
    		
			positionSwitch = -1;	//Initialisation
			
		    	// Balayer le tableau contenant les 5 id_echeance et les 5 echeance , tableauIdEcheances contient [10]éléments
	        	// Avec id_echeance et appelle la methode permattant de télécharger les cotations de chaque id_echeances
		        //contenu du tableau : 0 = id_echeance1, 1 = echeance1, 2 = id_echeance2, 3 = echeance2, 4 = id_echeance3, 5 = echeance3,...
			for(String IdEcheance : tableauIdEcheancesRetour){
	    		
		    		positionSwitch++;

				//positionSwitch = contenu du tableau : 0 = id_echeance1, 1 = echeance1, 2 = id_echeance2, 3 = echeance2, 4 = id_echeance3, 5 = echeance3,...
		    		//La position du switch récupere seulement les nombres impaires contenant les id_echeances
				switch (positionSwitch)
				{
				  case 0 :	
				  case 2 :	
				  case 4 :
				  case 6 :
				  case 8 :
				  	// 3 - Instancier la classe Activite_Cours_Asynctask_Recuperation_Cotations() 
				  	//------------------------------------------------------
		        		// La Classe Telecharge le fichier contenant les cotations par  id echéances et le parce
					// Le requete se fait par par l'intermédiare des idEcheances
					ObjetAsynctaskRecuperationCotations_3 = new Activite_Cours_Asynctask_Recuperation_Cotations(this, IdEcheance, retourIdClient);
					ObjetAsynctaskRecuperationCotations_3.execute();
				    	//------------------------------------------------------------------
			    		
					// 3.1 - Attente du résultat du traitement Asynctask 
			    		//Cela permet de récuperer les attributs de la clase Asynctask_3 "les cotations des articles" dans la classe "Activite_Cours"
			    		try {
			    			ObjetAsynctaskRecuperationCotations_3.get();
			    		} catch (InterruptedException e) {
			    			e.printStackTrace();
			    		} catch (ExecutionException e) {
			    			e.printStackTrace();
			    		}

			    		//-------------------------------------------------------
				    	// 4 - Remplissage des titres et des cotations dans le tableau objet (afin d'afficher les cotations)
			    		//------------------------------------------------------
				  	//Dans le "switch case", remplir le tableau avec les titres "String" aux position "indexTableauObjet++" 0:6:12:18:24,
				  	//en Sachant que "indexTableauObjet++" est indexé avant utilisation.
				  	//Si non, à l'exterieur du "switch case", remplir le tableau avec les cotations "objet" aux position 1:2:3:4:5, 7:8:9:10:11, ...
			    		...
				}//Fin switch 1		  	
	    		}//Fin For
		}//fin du For     de la bouble balayant le tableau des produits
    	
		// 5 - Appelle la classe "setListAdapter" afin d'afficher les cotations
		setListAdapter(new Remplissage_List());
		//-------------------------------------
	    	
		//Faire disparaitre le préload
    		progressDialog.dismiss();

	  //--------------------------
	} //Fin de la methode onCreate 
	  //--------------------------
Lien vers le commentaire
Partager sur d’autres sites

Merci l'ami Chpil de m'avoir répondu et d'avoir consacré un peut de votre temps pour m'aider à résoudre le petit problème d'affichage du preload.
Vu qu'il était impératif de lancer l'affichage (classe "BaseAdapter") dans la classe principale "ListActivity", et qu'il était impératif que les résultats des classes Asynctask soient bien arrivés pour le bon remplissage du tableau qui permet d'afficher les données, j'ai donc tout mis dans la classe principale (classe "BaseAdapter", et les 3 classes Asynctask).
J'ai travaillé dans les méthodes onPostExecute() des classes Asynctask pour récupérer les datas téléchargés puisque je ne pouvais utiliser la méthode get() qui attendait gentiment les résultats dans le onCreate().
Au début, mon programme été bien structuré. Je travaillais avec des classes Asynctask externes.
Depuis les modifications, le programme est beaucoup moins structuré puisque toutes mes classes secondaires se trouvent dans la classe principale mais le preload s'affiche correctement. Donc, il sera plus difficile à le maintenir si je doit le retravailler.
Pourriez vous, si vous plait, me conseiller pour mieux structurer le programme car dans ce bas monde, j'aime bien les choses bien faites.
Merci de votre aide.
Amicalement.
Didiericon_biggrin.gif

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...