Voici mon code:
protected Bitmap getImage(String imgurl) { try { URL url = new URL(imgurl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); int length = connection.getContentLength(); InputStream is = (InputStream) url.getContent(); byte[] imageData = new byte[length]; int buffersize = (int) Math.ceil(length / (double) 100); int downloaded = 0; int read; while (downloaded < length) { if (length < buffersize) { read = is.read(imageData, downloaded, length); } else if ((length - downloaded) <= buffersize) { read = is.read(imageData, downloaded, length - downloaded); } else { read = is.read(imageData, downloaded, buffersize); } downloaded += read; // publishProgress((downloaded * 100) / length); } Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0,length); if (bitmap != null) { System.out.println("Bitmap created"); } else { System.out.println("Bitmap not created"); } is.close(); return bitmap; } catch (MalformedURLException e) { System.out.println(e); } catch (IOException e) { System.out.println(e); } catch (Exception e) { System.out.println(e); } return null; }
5 Réponses :
La réponse simple est que la longueur du contenu est inconnu. Ou plus définissant précisément, le serveur est pas un en-tête « Content-Length » dans le message de réponse. P>
Vous devez changer votre code afin qu'il ne Préallouer pas un tableau d'octets de taille fixe pour contenir l'image. p>
Une alternative est de créer local Si vous pouvez changer le côté serveur, une autre alternative est de définir l'en-tête de la longueur du contenu de la réponse. Cela doit être fait avant d'obtenir le OutputStream pour écrire l'image octets à la réponse. P> li>
ul>
Vous le code existant est cassé dans un autre rapport aussi bien. Si vous obtenez un IOException ou d'une autre exception, le bloc de code « anormalement sortie » sans fermer la URLConnection. Cela se traduira par la fuite d'un descripteur de fichier. Pour ce faire, trop de fois et votre application échouera en raison de l'épuisement des descripteurs de fichiers ... ou les numéros de port locaux. P>
Il est préférable d'utiliser un try / finally pour faire en sorte que URLConnections, prises, cours d'eau et ainsi de suite à ce lien vers le bas des ressources externes sont toujours fermés. P> ByteArrayOutputStream code> et copiez octets lus dans la prise à ce sujet. Ensuite, appelez
toByteArray code> pour saisir le tableau d'octets complet. p> li>
Tout changement que vous m'avez recommandé dans l'application ou sur le côté serveur. N'importe quel code que j'ai besoin d'ajouter ici
Je prends vraiment l'exception, je n'ai pas simplement posté ce code ci-dessus, tout le code ci-dessus réside à l'intérieur d'essayer des déclarations de capture
Ce n'est pas seulement une question d'attraper l'exception. Vous devez fermer la connexion dans un bloc enfin aussi.
Bonjour, j'ai ajouté le code complet de la méthode que j'utilise dans la modification.
Oui. Je vois. Comme je m'attendais (et comme je l'ai expliqué ci-dessus), si une exception est levée entre l'ouverture de la connexion et la fermeture de l'introuvable, votre code est susceptible de fuir un descripteur de fichier de socket.
Lorsque le serveur utilise un codage de transfert chunté (commun pour les charges utiles volumineuses qui sont diffusées en continu), la longueur du contenu est inconnue et ne peut pas être dépendante. Il est très mauvais de tenter de pré-allouer un tampon pour toute la réponse, pouvez-vous dire déni de service code>? Voir la réponse ci-dessous concernant le codage de transfert ...
voir ici: http : ///download.oracle.com/javase/6/docs/api/java/net/urlconnection.html#getContElth%28%29 p>
Il dit, P>
retours: strong> p> La longueur du contenu de la ressource que l'URL de cette connexion références, ou -1 si la longueur du contenu n'est pas connue. P> blockQuote>
Cela signifie simplement l'en-tête ne contient pas le champ
longueur de contenu code>. Si vous avez le contrôle du code serveur. Vous devez définir le contenu-sous-traitant d'une manière utile. Quelque chose comme servleResponse # SetContentLength p>
La longueur du contenu de la ressource que la présente URL se réfère, ou -1 si la longueur du contenu n'est pas connue.
Je rencontre aussi ce problème dans mon application de papier peint. Le problème est que votre serveur ne fournit pas J'utilise un hôte de partage afin que je ne puisse pas modifier la configuration du serveur. Dans mon application, je suis défini la valeur de dialogue de progression Max avec une valeur approximée (qui est plus grande que ma taille de fichier réelle) comme ceci: p> Vous pouvez également vérifier mon exemple complet code source ici: p> P>
Il semble que le serveur n'offre pas longueur de contenu fort> dans ses en-têtes de réponse, avez-vous obtenu le codage de transfert = chunked fort> en-tête des en-têtes de réponse? Ma situation est la suivante: j'effectue une J'ai utilisé Wireshark pour analyser les deux demandes, trouvé une petite différence sur les en-têtes de demande. P> La liste d'en-tête qui utilise AndroidHTTPClient: P> la liste d'en-tête de demande qui utilise httpurlConnection: p> < Pré> xxx pré> La seule différence avec l'en-tête de la demande est Comme vous pouvez le constater, après avoir défini l'encodage accepté sur "Identity" Remplacer la valeur par défaut du système "Gzip", le serveur fourni "Contenu- Longueur "positif, c'est pourquoi AndroidhttpClient pourrait prendre la bonne valeur de la longueur de contenu et httpurlconnection non. p> L'encodage de la compression GZIP peut provoquer une réponse chuntée qui considère par le côté serveur, et si le serveur pense que vous pouvez recevoir une réponse de codage chuntée, elle peut ne pas offrir le contenu
Soyez conseillé: Désactiver le codage de transfert peut entraîner une question de performance sur le serveur, car il ne peut plus «diffuser» tout ce que vous avez demandé, et doit «calculer» toute la réponse avant de l'envoyer. Le meilleur plan est de ne pas dépendre de cet en-tête et de retirer simplement. Ceci est indépendant de la compression, etc.
Par défaut, cette implémentation de httpurlConnection demande que les serveurs utilisent la compression GZIP. alors essayez ceci: p> source (paragraphe de performance) : http://developer.android.com/reference/java/net/httpurlconnection. HTML P> P>
Depuis GetContentLength () renvoie le nombre d'octets transmis, vous ne pouvez pas utiliser cette méthode pour prédire le nombre d'octets pouvant être lus à partir de GetInputStream ().
Au lieu de cela, lisez ce flux jusqu'à ce qu'il soit épuisé: quand lire () retourne -1.
La compression GZIP peut être désactivée en définissant les codages acceptables dans l'en-tête de la demande:
Merci, c'est une réponse parfaite :)
Wow! Cela a fonctionné. J'étais sur le point de jeter mon ordinateur portable: p merci un paquet