我有一个简单的问题:虽然我正在使用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
?请不要发布任何有关如何从URL加载Bitmap
的初学者教程...
答案 0 :(得分:1)
只需使用HttpUrlConnection
即可获得该简单请求。
此外,您确定样本大小的方式是hackish,在解码为Bitmap
之前的内容大小不是确定Bitmap
字节分配的好方法,而是使用其维度。
答案 1 :(得分:1)
还要检查setFixedLengthStreamingMode
上的方法setChunkedStreamingMode
和HttpURLConnection
。考虑到它们,您可以在下载大图像时减少内存消耗。
仅供参考,您可以查看可能提供您尝试实现的功能的库。有些还支持缓存,这可能非常方便。
我知道的很少有
https://github.com/nostra13/Android-Universal-Image-Loader
答案 2 :(得分:0)
我对从互联网上加载的图片有类似的问题,我修复此问题的方法是将图像保存在手机的临时位置(您可以使用内部或外部存储,无所谓)并加载来自那里。将图像字节保存在文件中,使用缓冲区,不要在单个操作上读写所有字节。
这种方式很好用。我现在没有示例代码,我没有找到我使用这种技术的项目,但你可以使用谷歌方式从http中保存二进制资源。
稍后修改: 另一个类似的问题在这里被问到:Regarding download image from url in android
稍后编辑:
此流无法多次读取,在第一次读取时获取图像大小,然后转到另一个信息。这是您的错误的简短说明。编译器优化您的代码,以便能够从流中重新读取并将其放在内存中。发生这种情况时,会抛出OOM。