1

我有一个简单的问题:虽然我正确使用了 sampleSize,但我的代码甚至没有到达BitmapFactory代码,因为DefaultHttpClient已经抛出异常。

这是我的代码:

                DefaultHttpClient client = new DefaultHttpClient();
                HttpGet request = new HttpGet(mSongInfo.imageLarge);
                HttpResponse response = client.execute(request);
                int sampleSize = 1;
                while (response.getEntity().getContentLength() / sampleSize
                        / sampleSize > 100 * 1024) {
                    sampleSize *= 2;
                }
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = sampleSize;
                final Bitmap bitmap = BitmapFactory.decodeStream(response
                        .getEntity().getContent(), null, options);

这是一个例外:

0   java.lang.OutOfMemoryError: (Heap Size=11463KB, Allocated=7623KB, Bitmap Size=9382KB)
1       at org.apache.http.util.ByteArrayBuffer.<init>(ByteArrayBuffer.java:53)
2       at org.apache.http.impl.io.AbstractSessionInputBuffer.init(AbstractSessionInputBuffer.java:82)
3       at org.apache.http.impl.io.SocketInputBuffer.<init>(SocketInputBuffer.java:98)
4       at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83)
5       at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170)
6       at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106)
7       at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129)
8       at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:173)
9       at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
10      at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
11      at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
12      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
13      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
14      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
15      at de.goddchen.android.easysongfinder.fragments.SongFragment$1.run(SongFragment.java:79)
16      at java.lang.Thread.run(Thread.java:1027)

如您所见,代码甚至没有到达我检查图像大小(内容长度)并计算适当样本大小的部分。

我不知道简单的调用DefaultHttpClient.execute(...)已经将完整的内容加载到内存中。

难道我做错了什么?首先检索内容长度然后开始读取内容的正确方法是InputStream什么?

编辑 为了避免显示如何从 URL 加载图像的常见答案:我已经知道如何做到这一点,我也发布了上面的代码,那么你为什么要继续参考教程呢?我明确地非常清楚这个问题:为什么HttpClient.execute(...)已经获取了整个内容并将其存储在内存中而不是为InputStream我提供一个正确的?请不要发布任何关于如何Bitmap从 URL 加载的初学者教程...

4

3 回答 3

1

只需HttpUrlConnection用于那个简单的请求。

此外,您确定样本大小的方式是骇人听闻的,解码前的内容大小Bitmap不是确定Bitmap字节分配的好方法,请使用其尺寸。

于 2012-11-02T23:11:19.963 回答
1

还要检查方法setFixedLengthStreamingModesetChunkedStreamingModeon HttpURLConnection。考虑到它们,您可以在下载大图像时减少内存消耗。

仅供参考,您可以查看可能提供您尝试实现的功能的库。有些还支持缓存,这可能非常方便。

以下是我所知道的几个

https://github.com/nostra13/Android-Universal-Image-Loader

https://github.com/novoda/ImageLoader

https://github.com/kaeppler/ignition

于 2012-11-03T11:01:16.340 回答
0

我对从互联网加载的图像有类似的问题,我解决这个问题的方法是将图像保存在手机上的临时位置(您可以使用内部或外部存储,没关系)并从那里加载图像。将图像字节保存在文件中,使用缓冲区,不要在单个操作中读取和写入所有字节。

这样它就可以正常工作。我现在没有示例代码,我没有找到我使用这种技术的项目,但是您可以使用 google 方法从 http.xml 保存二进制资源。

稍后编辑:这里提出了另一个类似的问题:关于从 android 中的 url 下载图像

稍后编辑

这个流不能被多次读取,在第一次读取时获取图像大小,然后再获取另一个信息。这是对您的错误的简短解释。编译器优化您的代码,以便能够从流中重新读取并将其放在内存中。发生这种情况时,会抛出 OOM。

于 2012-11-02T22:45:59.213 回答