Android解码器 - >解码为位图下载返回false

时间:2010-12-02 19:40:33

标签: android android-layout

我已经开始了

DEBUG/skia(xxxx): --- decoder->decode returned false 

在我在ImageViews中使用的一些来自Facebook的个人资料图片上发布问题。大多数工作都很完美,但每隔一段时间我就会发现一个永远无法工作的东西。

出于向后兼容的原因,我正在针对Android 1.6编译我的应用程序。

我做了一些挖掘,发现了一些关于这个问题的线索。我已经在使用这里讨论的FlushedInputStream了:http://code.google.com/p/android/issues/detail?id=6066

Bitmap b = BitmapFactory.decodeStream(new FlushedInputStream(is));
imageView.setImageBitmap(b);

这是一个给我带来麻烦的例子: http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs269.snc3/23132_639284607_390_q.jpg

有人可以查看图片并帮我找出造成问题的原因吗?

7 个答案:

答案 0 :(得分:33)

FlushedInputStream(is)中存在错误。它在慢速连接时失败,但你可以尝试我的神奇代码来修复它。

Bitmap b = BitmapFactory.decodeStream(new FlushedInputStream(is));
imageView.setImageBitmap(b);

在方法之外创建一个静态类

 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;
        }
    }

然后你去..现在你不会有任何问题。

答案 1 :(得分:10)

这是一种对我有用的方法:

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);

答案 2 :(得分:5)

ImageDownloader.java的源代码是一个很好的方向。它有一个错误修复程序,通过提供修补的FlushedInputStream类来解决Issue 6066

您可能想要处理的另一件事是在执行HTTP请求的同一线程中执行解码:

@Override
protected Bitmap doInBackground(String... url) {
     // execute HTTP GET request and decode response
     ...
     return bitmap
}


@Override
protected void onPostExecute(Bitmap result) {
     imageView.setImageBitmap(result);
}

我在onPostExecute()中完成了解码,这是在UI线程中执行的,它不再起作用了,给了我同样的错误。

答案 3 :(得分:2)

这是一种对我有用的方法:

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;
    }

我通过多线程加载图像,然后当线程的时间由另一个人持有时,我不得不循环读取inputStream。确保完全读取inputStream。

答案 4 :(得分:1)

以下是我的问题:

从模拟器我将本地保存jpg文件(在模拟的SD卡上),然后尝试读取它并在模拟器上使用解码显示它并且它工作。然后,作为测试,我将文件(使用adb pull)复制到我的开发(xp)机器,它将使用'paint'显示。然后,从模拟器中,我将文件(通过http post)上传到我的win2003服务器。使用'paint'也显示在那里。但是当我将它下载回模拟器(通过http get)时,它在解码过程中失败了。

然后我注意到上传到win2003服务器的文件比原始文件小两个字节。不完全确定是怎么发生的,因为我多年来一直使用相同的上传逻辑,从未注意过这个问题。作为测试,我只是在上传过程中添加了两个随机字节,因此文件大小完全相同。然后,当下载回仿真器时,它会被正确解码并显示。

就像检查一样,我在我的xcode项目上添加了两个随机字节,然后这些jpg文件也显示在android模拟器上。

因此,尽管两个字节较小的文件显示在其他地方,但它们不会在模拟器上显示。显然解码是在尝试解码并决定无法继续之前进行某种CRC。因而错误。

答案 5 :(得分:1)

其他在Android KitKat 4.4中遇到问题的人将会有所帮助

Bitmap b = BitmapFactory.decodeStream(new BufferedInputStream(is));
imageView.setImageBitmap(b);

我在Nexus系列中遇到过这个问题。更新到4.4后。

答案 6 :(得分:0)

我也使用Xamarin遇到了这个问题。为了解决这个问题,我只使用了Universal Image Loader Xamarin Component,它就像一个魅力。

希望这有帮助!