I've started getting a
DEBUG/skia(xxxx): --- decoder->decode returned false
issue on a few profile images from Facebook that I use in ImageViews. Most work perfectly, but every once in a while I discover one that never works.
I am compiling my application against Android 1.6 for backward compatibility reasons.
I did some digging and discovered a number of threads on the issue. I'm already using the FlushedInputStream discussed here: http://code.google.com/p/android/issues/detail?id=6066
Bitmap b = BitmapFactory.decodeStream(new FlushedInputStream(is));
imageView.setImageBitmap(b);
Here's an example that's causing me trouble: http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs269.snc3/23132_639284607_390_q.jpg
Can someone check out the image and help me figure out what's causing the trouble?
There is a bug in FlushedInputStream(is). it fails on slow connections but you can try my magical code to fix it.
Bitmap b = BitmapFactory.decodeStream(new FlushedInputStream(is));
imageView.setImageBitmap(b);
create a static class outside your method
static class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
@Override
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int b = read();
if (b < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
and here you go.. now you will not have any problem.
Here is a way that worked for me:
HttpGet httpRequest = new HttpGet(url);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient
.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(entity);
InputStream is = bufferedHttpEntity.getContent();
Drawable d = Drawable.createFromStream(is, "");
//or bitmap
//Bitmap b = BitmapFactory.decodeStream(is);
The source code from this ImageDownloader.java is a good orientation. It has a bug fix which addresses the Issue 6066 by providing a patched FlushedInputStream
class.
Another thing which you might want to take care of, is to execute the decoding in the same thread as the HTTP request was executed:
@Override
protected Bitmap doInBackground(String... url) {
// execute HTTP GET request and decode response
...
return bitmap
}
@Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
I had done the decoding in the onPostExecute()
, which is executed in the UI thread, and it would not work anymore, giving me the same error.
Here is a way that worked for me:
public static Bitmap loadImageFromUrl(String url) {
URL m;
InputStream i = null;
BufferedInputStream bis = null;
ByteArrayOutputStream out =null;
try {
m = new URL(url);
i = (InputStream) m.getContent();
bis = new BufferedInputStream(i,1024 * 8);
out = new ByteArrayOutputStream();
int len=0;
byte[] buffer = new byte[1024];
while((len = bis.read(buffer)) != -1){
out.write(buffer, 0, len);
}
out.close();
bis.close();
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
byte[] data = out.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
//Drawable d = Drawable.createFromStream(i, "src");
return bitmap;
}
I loaded the image by multithreading, and then I had to loop reading the inputStream when the thread's time was held by another. Make sure the inputStream is read fully.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With