问题
I am trying to download an image from a URL to display as an ImageView. The download is done in the background using AsyncTask. However, the call to the decodeStream of the BitmapFactory always returns a null object. I verified that the Url provided for the connection is right, but it seems that BitmapFactory cannot read the image from the InputStream returned by the HTTP connection. Here is the code below:
@Override
protected Bitmap doInBackground(String... uri) {
Bitmap bm = null;
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(Uri.encode(uri[0]));
try {
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
String contentType = entity.getContentType().getValue();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int halfScreen = metrics.widthPixels / 2;
int photoWidth = halfScreen > 200 ? 200 : halfScreen;
if (contentType.contains("image/jpeg") || contentType.contains("image/png") || contentType.contains("image/gif")) {
bm = BitmapFactory.decodeStream(new BufferedInputStream(entity.getContent()));
if (bm.getWidth() > photoWidth)
bm = Bitmap.createScaledBitmap(bm, photoWidth, Math.round((photoWidth*bm.getHeight())/bm.getWidth()), true);
}
} catch (Exception e) {
bm = null;
}
return bm;
}
What is weird is that the exact same code runs fine on a Nexus S, but does not work on a Samsung running Android 2.1-update1.
回答1:
The problem was in the BitmapFactory.decodeStream() method. It seems that this method has a bug that makes it fail on slow connections. I applied the recommendations found at http://code.google.com/p/android/issues/detail?id=6066.
I created the FlushedInputStream class below:
public class FlushedInputStream extends FilterInputStream {
protected FlushedInputStream(InputStream in) {
super(in);
}
@Override
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int onebyte = read();
if (onebyte < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
Then, in my code I used:
bm = BitmapFactory.decodeStream(new FlushedInputStream(entity.getContent()));
instead of:
bm = BitmapFactory.decodeStream(new BufferedInputStream(entity.getContent()));
回答2:
Try to wrap your HttpEntity into BufferedHttpEntity, like it's done in this question: BitmapFactory.decodeStream returns null without exception . Seems that problem is quite similar.
来源:https://stackoverflow.com/questions/9011967/cannot-load-image-from-a-url-using-bitmapfactory-decodestream