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)

ご覧のとおり、画像のサイズ(Content-Length)を確認して適切なサンプルサイズを計算する部分にコードが到達していません。

DefaultHttpClient.execute(...)単に呼び出すだけで、完全なコンテンツがすでにメモリに読み込まれることを私は知りませんでした。

私は何か間違ったことをしていますか?最初にコンテンツの長さを取得してから、コンテンツの読み取りを開始する正しい方法は何InputStreamですか?

編集 URLから画像をロードする方法を示す一般的な回答を避けるために:私はすでにそれを行う方法を知っています、私は上記のコードも投稿しました、なぜあなたはそれに関するチュートリアルを参照し続けるのですか?私はこの問題について明確に明確にしました。HttpClient.execute(...)適切なコンテンツを提供するのではなく、コンテンツ全体をフェッチしてメモリに保存しているのはなぜInputStreamですか。URLからをロードする方法に関する初心者向けチュートリアルを投稿しないでくださいBitmap...

4

3 に答える 3

1

また、メソッドsetFixedLengthStreamingModesetChunkedStreamingModeを確認してください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 に答える
1

HttpUrlConnectionその単純な要求に使用するだけです。

また、サンプルサイズを決定する方法はハックです。デコードする前のコンテンツサイズは、バイト割り当てBitmapを決定するための良い方法ではありません。そのサイズを使用してください。Bitmap

于 2012-11-02T23:11:19.963 に答える
0

インターネットから読み込まれた画像でも同様の問題が発生しました。これを修正する方法は、画像を電話の一時的な場所に保存し(内部または外部のストレージを使用できますが、関係ありません)、そこから画像を読み込むことでした。イメージバイトをファイルに保存し、バッファを使用します。1回の操作ですべてのバイトを読み書きしないでください。

そして、このようにそれはうまく機能します。現在サンプルコードはありません。この手法を使用したプロジェクトは見つかりませんが、Googleの方法を使用してhttpからバイナリリソースを保存することができます。

後で編集:別の同様の質問がここで尋ねられました:AndroidのURLからの画像のダウンロードについて

後で編集

このストリームを複数回読み取ることはできません。最初に読み取ったときに画像サイズを取得し、その後、別の情報を取得します。これはあなたのエラーの簡単な説明です。コンパイラはコードを最適化して、ストリームから再読み取りしてメモリに配置できるようにします。これが発生すると、OOMがスローされます。

于 2012-11-02T22:45:59.213 に答える