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

Android解码器->;位图下载解码返回false,android,android-layout,Android,Android Layout,我已经开始得到一份工作了 DEBUG/skia(xxxx): --- decoder->decode returned false 在我在ImageView中使用的Facebook上的一些个人资料图片上发布。大多数都能很好地工作,但偶尔我会发现一个根本不起作用的 出于向后兼容性的原因,我正在针对Android 1.6编译我的应用程序 我做了一些挖掘,发现了一些关于这个问题的线索。我已经在使用这里讨论的FlushedInputStream: 下面是一个给我带来麻烦的例子: 有人能检查一

我已经开始得到一份工作了

DEBUG/skia(xxxx): --- decoder->decode returned false 
在我在ImageView中使用的Facebook上的一些个人资料图片上发布。大多数都能很好地工作,但偶尔我会发现一个根本不起作用的

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

我做了一些挖掘,发现了一些关于这个问题的线索。我已经在使用这里讨论的FlushedInputStream:

下面是一个给我带来麻烦的例子:


有人能检查一下图像并帮我找出问题的原因吗?

FlushedInputStream(is)中有一个bug。它在低速连接时失败,但你可以尝试我的神奇代码来修复它

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扩展FilterInputStream{
公共FlushedInputStream(InputStream InputStream){
超级(输入流);
}
@凌驾
公共长跳过(长n)引发IOException{
长的总重量=0升;
while(totalBytesSkipped

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

这里有一种方法对我很有效:

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

以下是一种对我有效的方法:

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);
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。确保输入流已被完全读取。

以下是我遇到的问题:

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

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

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

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

这篇文章的源代码是一个很好的方向。它有一个bug修复程序,通过提供修补的
FlushedInputStream
类来解决问题

您可能需要注意的另一件事是,在执行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);
}

我已经在UI线程中执行的
onPostExecute()
中进行了解码,它将不再工作,这给了我同样的错误。

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

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

在升级到4.4之后,我在Nexus系列中遇到了这个问题。

我在使用Xamarin时也遇到了这个问题。为了解决这个问题,我只是简单地使用了,它就像一个符咒


希望这有帮助

嗨,艾扎兹。我已经在用FlushedInputStream了。它不适用于我问题中列出的图像。我遇到了类似的问题,请尝试使用b.recycle();在kitkat中设置imageView的位图工作后,在Marshmallow中失败,在我的案例中也有效,但是有人解释这个问题吗?酷!这是正确的:)@marwinXXII:关键是使用缓冲,以避免解码时出现延迟问题。更多信息:我已经尝试了这里找到的每一段代码来解决上述问题。不幸的是,我无法解决它。我有一个大小超过2.5 MB的图像,正在从服务器下载。虽然我仍然可以从同一服务器下载任何其他大小小于1MB的图像,但我面临同样的问题,并尝试了你的代码,但它对我不起作用。我仍然会遇到同样的错误。在打开多个文件时会发生这种情况。似乎有一些内存文件访问限制。从装入的OBB文件中打开它们。可能是这样,在这样做之后,您仍然面临问题吗?