【问题标题】:Android decoder->decode returned false for Bitmap downloadAndroid 解码器-> 解码返回 false 用于位图下载
【发布时间】:2010-12-02 19:40:33
【问题描述】:

我已经开始买了

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

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

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

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

    给你..现在你不会有任何问题了。

    【讨论】:

    • 嗨艾扎兹。我已经在使用 FlushedInputStream。它不适用于我的问题中列出的图像。
    • 我在尝试使用 b.recycle(); 时遇到了同样的问题设置imageView的位图后
    【解决方案2】:

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

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

    【讨论】:

    • 酷!这是正确的:) @marwinXXII:关键是使用缓冲以避免解码时出现滞后问题。更多信息:gitshah.com/2011/05/fixing-skia-decoder-decode-returned.html
    • 我已经尝试了这里找到的每一段代码来解决上述问题。不幸的是我无法解决它。我有一个从服务器下载的大小超过 2.5 MB 的图像。虽然我仍然可以从同一服务器下载大小小于 1 MB 的任何其他图像
    【解决方案3】:

    来自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 线程中执行,它不再工作,给我同样的错误。

    【讨论】:

      【解决方案4】:

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

      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 被完整读取。

      【讨论】:

        【解决方案5】:

        这就是我的问题:

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

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

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

        因此,虽然小两个字节的文件会显示在其他任何地方,但它们不会在模拟器上显示。显然 decode 在尝试解码并决定它无法继续之前正在执行某种 CRC。因此出现错误。

        【讨论】:

          【解决方案6】:

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

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

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

          【讨论】:

            【解决方案7】:

            我在使用 Xamarin 时也遇到了这个问题。为了修复它,我简单地使用了Universal Image Loader Xamarin Component,它就像一个魅力。

            希望这会有所帮助!

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-06-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-07-21
              • 1970-01-01
              相关资源
              最近更新 更多