BitmapFactory.decodeStream方法返回null的错误分析

这个问题其实早就遇到了,由于停了几天电无法工作,今天就把这问题记录下分享下。利用BitmapFactory加载网络中的图片时,使用decodeStream方法会返回null的错误。主要是由于下面几个原因导致的:

  • 流已经关闭
  • decodeStream调用了两次
  • decodeStream的BUG(本文不讨论,详见参考文章)

这个问题很有意思,刚开始遇到的时候在国内外到找到许多不同的解决方法,在stackoverflow上也有提问相关的问题(详见参考文章),本人经过验证总结后和大家分享下。

  • 流已经关闭的解决方法
    出现这个问题的主要原因是解析网络流的代码写在了流关闭后,只需要分析清楚流在什么时候关闭即可。

  • decodeStream调用了两次的问题分析和解决方法
    本文主要对此情况进行分析:
    首先是如何重现这种问题,很显然为了得到图片的分辨率,一般都会先把inJustDecodeBounds设置为true,解析图片,这时候的decodeStream是必定返回null,api本身设计就是这样,

options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);

但是如果在上述代码再执行类似下面的代码,即再次调用decodeStream方法,这样的话就会出现返回的bitmap为null的问题。

options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);

如果直接不解析分辨率decodeStream的话可以正常返回Bitmap对象,这个原因很简单,第一次decodeStream时已经操作过inputstream了,这时候流的操作位置已经移动了,如果再次decodeStream则不是从流的起始位置解析,所以无法解析出Bitmap对象。
只需要添加下面代码使流读写位置恢复为起始位置即可:

is.reset();

这个其实在源代码中有提示需要考虑流的读取位置变化的问题。

个人建议是,既然需要优化Bitmap的显示,如果做缓存的话,建议把InputStream网络流写到文件,利用decodeFile方法来解析就不存在上述的问题。(decodeFile内部是调用了decodeStream解析本地流)
个人认为网上有些把网络流重新再读取一次这种做法不合理,不但浪费用户流量而且会使处理变慢,另外一些把流包装了再处理的个人感觉不如写到本地再解析。

decodeStream的源代码

 public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {
        // we don't throw in this case, thus allowing the caller to only check
        // the cache, and not force the image to be decoded.
        if (is == null) {
            return null;
        }

        // we need mark/reset to work properly

        if (!is.markSupported()) {
            is = new BufferedInputStream(is, DECODE_BUFFER_SIZE);
        }

        // so we can call reset() if a given codec gives up after reading up to
        // this many bytes. FIXME: need to find out from the codecs what this
        // value should be.
        is.mark(1024);

    ...

声明

原创文章,欢迎转载,请保留出处。
有任何错误、疑问或者建议,欢迎指出。
我的邮箱:[email protected]

参考文章

decodeStream的BUG: http://endual.iteye.com/blog/1629549/
stackoverflow上的讨论:https://stackoverflow.com/questions/2503628/bitmapfactory-decodestream-returning-null-when-options-are-set

你可能感兴趣的:(android,bitmap,Stream,null,网络图片)