在Android上,如果输入流不为空但仍返回null,则BitmapFactory.decodeStream(InputStream is)方法存在问题。

5
我正在开发一款Android应用程序,它的视图包含多个画廊。画廊的内容(位图)从互联网中读取。
对于第一个画廊,一切正常,但是当尝试下载第二个画廊的第一张图片时,BitmapFactory.decodeStream(InputStream)返回null,而流不为null。
public void loadBitmap() throws IOException {

        for (int i = 0; i < images.size(); ++i) {
            URL ulrn = new URL(images.get(i).getThumbUrl());
            HttpURLConnection con = (HttpURLConnection) ulrn.openConnection();
            InputStream is = con.getInputStream();
            images.get(i).setImage(BitmapFactory.decodeStream(is));
            Log.i("MY_TAG", "Height: " + images.get(i).getImage().getHeight());
        }
}
getThumbUrl()返回图片的URL(例如:http://mydomain.com/image.jpg),在Log.i("MY_TAG", "Height: ... )这一行会抛出NullPointerException异常(images是一个包含我的类对象的ArrayList,该类对象保存了URL和位图)。
感谢任何建议!

不是太大,我会说大约100x50。但如果那是问题,我会得到一些OutOfMemoryException,不是吗?(我正在向画廊加载大约30-35张图片,并且每次加载大约10张稍微大一点的图片) - Ripityom
3个回答

7

我遇到了这个问题。尝试使用带有输入流的BufferedHttpEntity。我发现这可以防止解码流时出现99.9%的静默null值。

也许不重要,但是我可靠地使用org.apache.http.client.HttpClient而不是HttpURLConnection,例如:

public static Bitmap decodeFromUrl(HttpClient client, URL url, Config bitmapCOnfig)
{
    HttpResponse response=null;
    Bitmap b=null;
    InputStream instream=null;

    BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
    decodeOptions.inPreferredConfig = bitmapCOnfig;
    try
    {
    HttpGet request = new HttpGet(url.toURI());
        response = client.execute(request);
        if (response.getStatusLine().getStatusCode() != 200)
        {
            MyLogger.w("Bad response on " + url.toString());
            MyLogger.w ("http response: " + response.getStatusLine().toString());
            return null;
        }
        BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(response.getEntity());
        instream = bufHttpEntity.getContent();

        return BitmapFactory.decodeStream(instream, null, decodeOptions);
    }
    catch (Exception ex)
    {
        MyLogger.e("error decoding bitmap from:" + url, ex);
        if (response != null)
        {
            MyLogger.e("http status: " + response.getStatusLine().getStatusCode());
        }
        return null;
    }
    finally
    {
        if (instream != null)
        {
            try {
                instream.close();
            } catch (IOException e) {
                MyLogger.e("error closing stream", e);
            }
        }
    }
}

嗯...我在一个视图中使用了上述代码,并成功地将其与两个画廊配合使用。你遇到了什么样的错误? - mmeyer
我没有收到任何错误信息,返回的 Bitmap 为空。这很奇怪,因为我已经把错误消息包含在代码中了。 - Ripityom
现在应用程序已经加载了所有图像,但我收到了以下错误:“05-10 10:31:19.553:ERROR / dalvikvm-heap(26407):582400字节的外部分配对于此进程过大。” 我认为这是一个内存问题,但是为什么我没有得到异常呢? - Ripityom
好的,很好。这是一个不同的问题。要么你的1个位图太大了,要么画廊中的视图没有得到回收,所有其他的位图仍然在内存中,而导致错误的那个位图就像压垮骆驼的最后一根稻草一样。看看这篇文章:https://dev59.com/207Sa4cB1Zd3GeqP7N2L - mmeyer
谢谢你解释了那个。 - Ripityom
显示剩余4条评论

1

1
FlushedInputStream 对我没用。但是 @mmeyer 的解决方案有效。 - user123321

0
public static Bitmap decodeStream (InputStream is)

返回

解码后的位图,如果无法解码图像数据,则为 null。

您是否检查了是否获取到了 404 错误或类似错误而不是图像?


嗨!是的,我已经注销了URL,复制到浏览器中,然后浏览器打开了该图像。 - Ripityom
检查 con.getResponseCode(); 的值是否为200(HTTP_OK)。 - Aleadam
是的,它是200,所以流似乎很好。 - Ripityom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接