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 :

Problème affichage d'une boite ProgressDialog entre 2 activités


Sujet :

Android

  1. #1
    Invité
    Invité(e)
    Par défaut Problème affichage d'une boite ProgressDialog entre 2 activités
    Bonsoir à tous,

    J'ai un problème sur lequel je bloque depuis de nombreuses heures et qui je pense ne doit pas être très compliqué à résoudre, je m'explique:

    J'ai 2 activités,
    - La première me permet d'accéder à la deuxième en appuyant sur un bouton.

    - Ma deuxième activité est une ListView qui comporte une image (téléchargée sur un serveur HTTP), un titre et une description. Cette ListView est affichée à l'aide d'un adaptateur personnalisé que j'ai crée dérivant de BaseAdapter.

    Le problème c'est que dans la méthode getView() de cet adaptateur personnalisé je fais des requêtes HTTP afin de récupérer les images, ce qui est un processus assez lent. Je voudrai donc mettre une boite de dialogue de type ProgressDialog afin d'indiquer à l'utilisateur de patienter un peu avant l'affichage de la liste mais je n'y arrive pas...

    Toutes mes tentatives (à l'aide de thread etc..) ont échoué : la boite de dialogue n'apparaissait jamais ou que très rapidement après un long écran noir (celui pendant lequel je voudrai qu'elle s'affiche ...).

    J'espère avoir été clair et vous remercie d'avance pour votre aide

  2. #2
    Membre extrêmement actif
    Profil pro
    Développeur
    Inscrit en
    Mars 2012
    Messages
    1 970
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2012
    Messages : 1 970
    Par défaut
    Tu devrais employer un AsyncTask et coder ton progress dans les onPreExecute, onPostExecute, onProgressUpdate

    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
    private class BigCalcul extends AsyncTask<Void, Integer, Void>
    {
     
    	@Override
    	protected void onPreExecute() {
    		super.onPreExecute();
    		Toast.makeText(getApplicationContext(), "Début du traitement asynchrone", Toast.LENGTH_LONG).show();
    	}
     
    	@Override
    	protected void onProgressUpdate(Integer... values){
    		super.onProgressUpdate(values);
    		// Mise à jour de la ProgressBar
    		mProgressBar.setProgress(values[0]);
    	}
     
    	@Override
    	protected Void doInBackground(Void... arg0) {
     
    		int progress;
    		for (progress=0;progress<=100;progress++)
    		{
    			for (int i=0; i<1000000; i++){}
    			//la méthode publishProgress met à jour l'interface en invoquant la méthode onProgressUpdate
    			publishProgress(progress);
    			progress++;				
    		}	
    		return null;
    	}
     
    	@Override
    	protected void onPostExecute(Void result) {
    		Toast.makeText(getApplicationContext(), "Le traitement asynchrone est terminé", Toast.LENGTH_LONG).show();
    	}
    }

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci de ta réponse, je vais essayer et te tient au courant

  4. #4
    Invité
    Invité(e)
    Par défaut
    Alors, grâce à AsyncTask j'arrive à faire en sorte que ma liste s'affiche avec une image qui indique le chargement pour chaque item le temps que la bonne image ai été téléchargé.

    Cependant, j'ai un bug que je n'arrive pas à résoudre --' : durant le chargement de chacune des images, parfois, l'image d'attente est remplacée par une succession de plusieurs images qui correspondent aux images qui doivent s'afficher sur les autres item de la liste (en cours de téléchargement).
    De plus, l'image qui doit se trouver à l'item N°i se trouve quelque fois à l'item N°j ..

    J'espère avoir été assez clair , merci d'avance de votre aide.

  5. #5
    Membre extrêmement actif
    Profil pro
    Développeur
    Inscrit en
    Mars 2012
    Messages
    1 970
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2012
    Messages : 1 970
    Par défaut
    Ca me fait penser aux problèmes parfois avec les ressources files, de string décalées, d'un composant à l'autre, si tu le testes avec l'émulateur.

    Dans ce cas, je réinstalle l'applic (désinstalle et réinstalle).

  6. #6
    Invité
    Invité(e)
    Par défaut
    Je viens de désinstaller/réinstaller l'application et le problème est toujours le même
    Voici le code de mon adaptateur qui fait appel à la fonction de traitement asynchrone (je pense que le problème vient de là) :
    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
     
    public class BonsPlansAdapter extends BaseAdapter{
    	protected List<Societe> entreprise;
    	protected LayoutInflater inflater;
    	protected static Context context;
     
    	public BonsPlansAdapter(Context context, List<Societe> entreprise)
    	{
    		this.entreprise = entreprise;
    		inflater = LayoutInflater.from(context);
    		this.context = context;
    	}
     
    	public int getCount() {
    		return entreprise.size();
    	}
     
    	public static Context getContext()
    	{
    		return context;
    	}
     
    	public Object getItem(int position) {
    		return entreprise.get(position);
    	}
     
    	public long getItemId(int position) {
    		return position;
    	}
     
    	static class ViewHolder {
    		  public ImageView img;
    		  public TextView titre;
    		  public TextView description;
    		}
     
    	public View getView(int position, View convertView, ViewGroup parent) {
    		  ViewHolder holder = null;
     
    		  // Si la vue n'est pas recyclée
    		  if(convertView == null) {
    			holder = new ViewHolder();
     
    		    // On récupère le layout
    		    convertView  = inflater.inflate(R.layout.affichageitem, null);
     
    		    // On place les widgets de notre layout dans le holder
            	holder.titre = (TextView) convertView.findViewById(R.id.titre);
    		    holder.description = (TextView) convertView.findViewById(R.id.description);
    		    holder.img = (ImageView) convertView.findViewById(R.id.img);		        
     
    		    // puis on insère le holder en tant que tag dans le layout
    		    convertView.setTag(holder);
    		  } else {
     
    			  // Si on recycle la vue, on récupère son holder en tag
    		    holder = (ViewHolder)convertView.getTag();
    		  }
     
    		// On place dans le holder les informations sur la societe
    		holder.img.setImageResource(R.drawable.chargement);				
    		holder.description.setText(entreprise.get(position).getDescriptionBonPlan());
    	    holder.titre.setText(entreprise.get(position).getNom()); // Insertion d'une image d'attente (pendant le telechargement)
     
    	    // Telechargement de l'image qui sera affiché après
    	    DownloadImageTask telecharger = new DownloadImageTask(holder.img);
    		telecharger.execute(entreprise.get(position).getLogo());
     
    	    return convertView;
    	}
    Merci pour ton aide

  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
    Il faudrait le code du DownloadImageTask

  8. #8
    Invité
    Invité(e)
    Par défaut
    Le voici :

    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
     
    public class DownloadImageTask extends AsyncTask<String, Drawable, Drawable> {
     
    	private static HashMap<String, Drawable> listImages = new HashMap<String, Drawable>();	
    	private final WeakReference<ImageView> imageViewReference;
     
    	public DownloadImageTask(ImageView imageView){
    		super();
    		imageViewReference = new WeakReference<ImageView>(imageView);
    	}
     
    		@Override
    		protected Drawable doInBackground(String... url) {
     
    			Drawable d = loadImageFromUrl(url[0]);
     
    			return d;
     
    		}
     
    		@Override
    		protected void onProgressUpdate(Drawable...d){
     
     
    		}
     
     
     
     
     
    		@Override
    		protected void onPostExecute(Drawable d) {
     
     
    	        if (imageViewReference != null) {
    	            ImageView imageView = imageViewReference.get();
    	            if (imageView != null) {
    	            	if(d != null)
    	            		imageView.setImageDrawable(d);
    	            }
    	        }
     
    		}
     
     
     
     
     
     
    	public static Drawable loadImageFromUrl(String url) {
     
    		  if (!listImages.containsValue(url)) {
    		    InputStream inputStream;
    		    try 
    		    {
    		      inputStream = new URL(url).openStream();
    		    } 
    		    catch (IOException e) 
    		    {
    		      throw new RuntimeException(e);
    		    }
     
    		    Drawable dr = null;
     
    		    try
    		    {
    		    dr = Drawable.createFromStream(inputStream, "src");
    		    }
    		    catch(Exception e)
    		    {
     
    		    }
    		    if(dr != null)
    		    	listImages.put(url, dr);
     
    		   return dr;
     
    		  } else {
     
    		     return listImages.get(url);
     
    		  }
     
    	}
     
     
     
    }

  9. #9
    Invité
    Invité(e)
    Par défaut
    Une idée? Voyez vous une erreur dans ce que j'ai fait ?

  10. #10
    Membre extrêmement actif
    Profil pro
    Développeur
    Inscrit en
    Mars 2012
    Messages
    1 970
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2012
    Messages : 1 970
    Par défaut
    final avec weakreference?!

  11. #11
    Membre confirmé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2012
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 36
    Par défaut
    tu peux essayer de mettre dans onProgessupdate le code d'affichage de la vue qui doit s'afficher le temps de téléchargement de la photo, et ensuite , tu crées une sorte de Handler qui permet d'informer que le traitement de téléchargement est terminé, et donc à ce moment là la méthode qui affiche la photo peut être appelée. car d'après la description de bug que tu nous a donné, j'ai l'impression que l'affichage de la photo interfère avec ta fenêtre d'attente.

  12. #12
    Invité
    Invité(e)
    Par défaut
    Erreur d’inattention hotcryx, je viens d'essayer Rokia88 mais le problème est toujours là...

    Je ne comprend vraiment plus rien là --'

  13. #13
    Membre extrêmement actif
    Profil pro
    Développeur
    Inscrit en
    Mars 2012
    Messages
    1 970
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Mars 2012
    Messages : 1 970
    Par défaut
    J'espère que tu as adapté ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    protected Drawable doInBackground(String... url) {
     
    	Drawable d = loadImageFromUrl(url[0]);
     
    	return d; 
    }
    ouille un catch vide dans loadImageFromUrl:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    catch(Exception e)
    {
     
    }

  14. #14
    Invité
    Invité(e)
    Par défaut
    Oui oui je l'ai adapté
    Je ne comprend vraiment pas pourquoi ça beug

  15. #15
    Membre confirmé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2012
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 36
    Par défaut
    je sais pas si la proposition que je vais te donner résoudra ton bug, mais par expérience, les inputstream produisent des comportement incompréhensibles. donc , je te propose d'ajouter un finally à ta méthode loadImageFromUrl pour fermer le inputstream que tu as ouvert en début de la méthode loadImageFromUrl.

  16. #16
    Modérateur
    Avatar de Hizin
    Homme Profil pro
    Développeur mobile
    Inscrit en
    Février 2010
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Par défaut
    Bon, déjà, PAS DE CATCH VIDE. Tu logs quelques part, tu fais quelque chose d'utile, mais pas d'exception silencieuse. Si c'est la, c'est pour une raison.

    Ensuite, pour ton souci :
    Tu les vois en multiple car tes ImageView sont réutilisées entre-temps.

    Situation de départ : tu affiches ta ListView, les X premiers items sont là, les images correspondantes sont en train d'être téléchargées et seront affichées dans les ImageView passés en paramètre.

    Situation suivante : le téléchargement des images est en cours, tu fait un peu défiler ta liste de 3 items. Les 3 ImageView de départ sont remplacées par 3 autres en apparence, mais en réalité, ce sont les même qui sont réutilisées. Les 3 nouveaux items lancent le téléchargement de leurs images respectives.

    Situation semi-finale : Tu n'as plus bougé ton UI. Le téléchargement des premiers items est finis. Tu t'aperçois maintenant que tes 3 nouveaux items obtenus précédemment ont des images qui ne sont pas les bonnes.

    Situation finale : les derniers items finissent leur téléchargement, les 3 "nouveaux" items ont bien les bonnes images.

    Bilan : ne pas passer l'ImageView, celle-ci étant réutilisée. Il faut lui passer le holder, le mettre à jour avec l'image puis dire gentiment au ArrayAdapter que les données ont un peu changé dans le holder et qu'il doit se redessiner (via notifyDataSetChanged()).

    Doc : http://developer.android.com/referen...tChanged%28%29
    Remarque : c'est pas simple à expliquer ce machin ...
    C'est Android, PAS Androïd, ou Androïde didiou !
    Le premier est un OS, le second est la mauvaise orthographe du troisième, un mot français désignant un robot à forme humaine.

    Membre du comité contre la phrase "ça marche PAS" en titre et/ou explication de problème.

    N'oubliez pas de consulter les FAQ Android et les cours et tutoriels Android

  17. #17
    Invité
    Invité(e)
    Par défaut
    Concernant le catch vide c'est corrigé.

    Hizin je viens d'implémenter une solution qui ressemble à ce que tu m'as expliqué et qui fonctionne : donc merci à tous pour votre aide très précieuse !

    Et passez de joyeuses fêtes

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

Discussions similaires

  1. problème d'affichage d'une boite de dialog à aprtir d'un menu
    Par meryeminfo dans le forum Interfaces Graphiques en Java
    Réponses: 2
    Dernier message: 15/12/2009, 16h11
  2. affichage dans une boite de texte en fonction d'un choix
    Par bachilbouzouk dans le forum ASP
    Réponses: 3
    Dernier message: 19/04/2005, 14h53
  3. [mfc] affichage dans une boite de dialog
    Par chronos dans le forum MFC
    Réponses: 3
    Dernier message: 14/06/2004, 15h12
  4. Réponses: 2
    Dernier message: 01/05/2004, 12h19
  5. Affichage d'une boite de dialogue nonmodale avec MFC
    Par the.cable.guy dans le forum Windows
    Réponses: 3
    Dernier message: 04/07/2003, 17h59

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