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 :

BitmapFactory.decodeStream(.) qui retourne null ?


Sujet :

Android

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2012
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Juillet 2012
    Messages : 75
    Points : 42
    Points
    42
    Par défaut BitmapFactory.decodeStream(.) qui retourne null ?
    Bonjour a tous,

    Dans une activité - enfin un fragment en réalité - j'affiche une liste Bitmap dans une listview. Jusqu'ici pas de problème, tout le monde suit.
    Cette liste est crée dans le main. Thread de parsing xml et tout le bazar... les Url sont bien récupérées, je convertis donc chaques urls en image bitmap dans ma liste Bitmap et hop, ca fonctionne bien, ca s'affiche et voila c'est tout beau.
    C'etait sans compter le fait que je testais l'application avec un galaxy S3, forcement en testant sur un vieux htc wildfire, j'ai remarqué que les images ne s'affichent plus, a part la premiere, et une ou deux images au milieu. Je debug a coup de Log et hop :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bitmap = BitmapFactory.decodeStream(is);
    me retourne nul. -> uniquement avec des telephones pas tres puissant.

    Voila le code qui s'occupe de la conversion url a bitmap : (Il pourra donc servir aux autres qui recherche justement une méthode dans ce style)

    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
    public Bitmap downloadImageJacket(String fileURL) 
    {
    	Bitmap bitmap = null;
    	URL myFileURL = null;
    	BitmapFactory.Options options = new BitmapFactory.Options();
    	options.inJustDecodeBounds = true;
    	try
    	{
    		myFileURL = new URL(fileURL);
    		HttpURLConnection conn = (HttpURLConnection)myFileURL.openConnection();
    	conn.setDoInput(true);
    	conn.connect();
    	InputStream is = conn.getInputStream();
    	bitmap = BitmapFactory.decodeStream(is);
    // bitmap = null au bout de la 2eme image de la liste, dans le cas de telephone non puissant ...
    	conn.disconnect();
    	} 
    	catch (IOException e) 
    	{
    	}
    	return bitmap; 
    }

    Voila, si vous avez tout saisi, j'ai besoin de votre aide.
    Merci !

  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
    Déjà commence par ne pas passer sous silence l'exception... on sait jamais ... des fois qu'il y en ai une....


    La règle d'un catch est simple:

    1. On peut récupérer de l'exception (et continuer le travail)...
    * On fait un Log.w() juste histoire d'avoir une trace quelque part.
    * On récupère ce qu'on peut

    2. C'est une vraie erreur (stopper)
    2.a. On veut passer l'erreur à l'appelant: On fait un autre throw new XXXXX (en changeant l'exception sinon, pas la peine de faire le catch) sans oublier de passer l'exception initiale en 'cause'.
    2.b. On veut l'afficher à l'utilisateur: On fait un Log.e() et on affiche le message, on se garde un chemin de retour dans la pile sans autre erreur... A noter qu'il est possible d'utiliser le mecanisme 2.a. pour laisser l'appelant l'afficher à l'utilisateur.

    Dans le cas d'un thread, if faut passer l'exception, d'une manière ou d'une autre, au thread UI, que ce soit par appel de fonction (runOnUiThread), ou par message (handle.postMessage)


    Et enfin, pour finir, sur la gestion des ressources l'objet de connection ne sera rendu quand lors d'un garbage collection... il y a fort à parier que le nombre de connections ouvertes est limité...

    On gère le truc de la manière suivante en général:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Connection conn = null;
    InputStream is = null;
    try {
       conn = ...openConnection();
       ...
       is = conn.getInputStream();
       ...
    } finally {
       if (is != null) try { is.close(); } catch(Exception ex) { Log.e(MONAPP,"Failed to gracefully close connection's stream",ex);
       if (conn != null) try { conn.disconnect(); } catch (Exception ex) { Log.e(MONAPP,"Failed to gracefully close connection !",ex); }
    }
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2012
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Juillet 2012
    Messages : 75
    Points : 42
    Points
    42
    Par défaut
    Oui, mais la n'étais pas ma question ...

    Dans le cas d'un telephone puissant toutes les images se telechargent bien et s'affichent, et dans le cas inverse il n'y a qu'une image ou deux, rarement les meme a chaques test ( a part la premiere ) qui s'affichent. Car BitmapFactory.decodeStream retourn null dans le bitmap.

    Je ne comprends pas pourquoi

  4. #4
    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
    Ben désolé... moi ça me file des boutons les catch() vide
    (d'ailleurs je conseille de dire à eclipse de traiter ces cas comme des erreurs, et de changer le 'default code' d'un catch en Log android).

    Comment sais tu que c'est BitmapFactory.decodeStream() qui retourne null ?
    C'est pas downloadImageJacket qui retourne null ?
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  5. #5
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2012
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Juillet 2012
    Messages : 75
    Points : 42
    Points
    42
    Par défaut
    Je l'ai su a coup de Log ,
    un simple Log.e("BONJOUR", ""+bitmap.toString());

    le premier passe, et affiche l'image et un string dans le log, le deuxieme est null ( java null sur le toString)

  6. #6
    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
    Sauf que ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Log.e("BONJOUR", ""+bitmap.toString());
    Ca crash si bitmap est null ! ....
    (d'ailleurs ""+ ne sert à rien)
    Java va faire:
    StringBuilder builder = new StringBuilder("");
    builder.append(bitmap.toString());
    builder.toString();
    Donc autant faire bitmap.toString() directement.


    Par contre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Log.e("BONJOUR", ""+bitmap);
    Lui ne crash pas...
    Java va faire:
    StringBuilder builder = new StringBuilder("");
    builder.append(bitmap); // si bitmap est null, ca va mettre 'null'
    builder.toString();


    Dans tous les cas, commence par gérer correctement les exceptions et surtout les ressources (connection/inputstream) comme indiqués dans mon premier message... on verra bien
    au passage tu peux rajouter un test genre:
    if (bitmap == null)
    Log.w("MONAPPLI", "Décodage depuis '"+url+"' échoué !");

    Au moins tu auras les URLs et le log quand il n'y a pas d'image.
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  7. #7
    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 : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Points : 5 072
    Points
    5 072
    Par défaut
    Accessoirement, cette méthode ne peut pas te retourner un "null" sans une exception (ou alors, je n'ai pas connaissance de ce cas de figure). Donc, en masquant totalement tes exceptions, tu t'empêches de débugger.
    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

  8. #8
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2012
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Juillet 2012
    Messages : 75
    Points : 42
    Points
    42
    Par défaut
    Oui, je sais merci ^^ mais c'est pas ca que j'essaye de faire comprendre enfaite...
    si une meme url BitmapFactory.decodeStream() reussis sur un samsung Galaxy s3, et toutes les images s'affichent. Mais BitmapFactory.decodeStream() renvoit null sur un telephone pas tres puissant. Surement parce que la connection a l'url de l'image et la conversion mettent trop de temps a se faire et se fait "ecraser" par la suivante avant qu'elle ai pu se finir...
    Donc, help ! haha

    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
    public Bitmap downloadImageJacket(String fileURL) 
    	{
    		Bitmap bitmap = null;
    		URL myFileURL = null;
    		BitmapFactory.Options options = new BitmapFactory.Options();
    		options.inJustDecodeBounds = true;
     
    		try 
    		{
     
    			myFileURL = new URL(fileURL);
    			HttpURLConnection conn = (HttpURLConnection)myFileURL.openConnection();
    			conn.setDoInput(true);
    			conn.connect();
    			InputStream is = conn.getInputStream();
    			bitmap = BitmapFactory.decodeStream(is);
     
    			conn.disconnect();
    			// TODO
    			// Log.e("PASSE", ""+bitmap.toString());
    		} 
    		catch (IOException e) 
    		{
    Log.e("MON PROBLEME", "n'est pas la... Car ca ne passe jamais ici");
    		}
    		return bitmap; 
    	}
    je dois surement faire quelque chose pour attendre que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bitmap = BitmapFactory.decodeStream(is);
    finisse avant de passer a la suite, mais quoi mettre ?

    ps : Ce ne passe jamais dans le catch

  9. #9
    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
    Désolé... il n'y a toujours pas de close sur l'input-stream
    ni de disconnect sur l'url connection (en cas d'erreur)
    tu ne trace toujours pas l'exception (manque ',e' dans l'appel du log).

    Sinon... BitmapFactory.decodeStream est synchrone, donc tu n'as pas a "attendre".... c'est bien pour cette raison que tout le code de récupération des images est à priori dans un thread à part.

    J'ai une liste qui récupère deux images par URL à chaque entrée, et qui passe sans problème sur Sony XPeria datant de mathusalem...
    D'ailleurs, l'émulateur est encore pire (moins de mémoire) de ce coté là...

    Peut-être cela vient-il de l'environnement de l'appel "downloadImageJacket"... peux tu nous montrer le code en question ?
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  10. #10
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2012
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Juillet 2012
    Messages : 75
    Points : 42
    Points
    42
    Par défaut
    Ah bah j'ai reussi, j'ai simplement rajouté un while ahah, mais par contre ce n'est pas du tout optimisé, et bien sale !

    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
    try 
    		{
                          while (bitmap == null)
    			{
    			myFileURL = new URL(fileURL);
    			HttpURLConnection conn = (HttpURLConnection)myFileURL.openConnection();
    			conn.setDoInput(true);
    			conn.connect();
    			InputStream is = conn.getInputStream();
    			bitmap = BitmapFactory.decodeStream(is);
     
    			conn.disconnect();
    			// TODO
    			// Log.e("PASSE", ""+bitmap.toString());
    		} 
    }
    Et ca marche désormais !

    Enfaite, vu le nombre important d'image et donc de connection a faire, sur les petits telephones la connection devait mal se faire, je sais pas .. enfin voila ! aha

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

Discussions similaires

  1. [MySQL] Requete qui retourne null
    Par stomerfull dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 25/07/2012, 14h37
  2. Requête avec jointure qui retourne null si pas de valeur
    Par jubourbon dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/09/2011, 11h10
  3. POI: GetRow qui retourne null
    Par ginkas31 dans le forum Documents
    Réponses: 3
    Dernier message: 12/12/2007, 15h14
  4. GetFont() qui retourne NULL
    Par aljattari dans le forum MFC
    Réponses: 3
    Dernier message: 27/04/2007, 21h06
  5. Réponses: 3
    Dernier message: 02/03/2007, 11h41

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