2012-02-14 4 views
0

これらの例外がユーザーから多く発生しています。java.lang.OutOfMemoryError:ビットマップサイズがVM予算を超えていますが、エミュレータで問題を再現できません。OutOfMemory URLから画像をデコードするとき

私はこれを私のImageDownloader http://code.google.com/p/android-imagedownloader/source/browse/trunk/src/com/example/android/imagedownloader/ImageDownloader.java#185として使用しています。画像をデコードしようとすると、問題は185行目で発生します。

このエラーに関して、stackoverflowには他にも多くの質問がありますが、私の具体的なケースに合った質問はありません。この質問の解決策は動作する可能性があります:https://stackoverflow.com/a/823966しかし、私はそれを動作させるように見えることはできません。ここで

は私ImageDownloaderに変更するものである:decodeStream()二回目の呼び出し時

final HttpEntity entity = response.getEntity(); 
if (entity != null) { 
    InputStream inputStream = null; 
    try { 
     inputStream = entity.getContent(); 
     // return BitmapFactory.decodeStream(inputStream); 
     // Bug on slow connections, fixed in future release. 

     FlushedInputStream flushedStream = new FlushedInputStream(inputStream); 

     // Decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeStream(flushedStream, null, o); 
     Log.d(LOG_TAG, "decodeStream - outWidth=" + o.outWidth + " outHeight=" + o.outHeight); 

     // The new size we want to scale to 
     final int REQUIRED_SIZE = 70; 

     // Find the correct scale value. It should be the power of 
     // 2. 
     int scale = 1; 
     while (o.outWidth/scale/2 >= REQUIRED_SIZE && o.outHeight/scale/2 >= REQUIRED_SIZE) 
      scale *= 2; 

     // Decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     return BitmapFactory.decodeStream(flushedStream, null, o2); 
    } finally { 
     if (inputStream != null) { 
      inputStream.close(); 
     } 
     entity.consumeContent(); 
    } 
} 

それが失敗しました。エラーはSkImageDecoder :: Factoryはヌルを返しました。私はおそらくinputStreamが閉じられているか、2番目の呼び出しで利用できないと考えたので、上記の最初の行でBufferedHttpEntityを使用しようとしましたが、運がありません。

誰かが私を正しい方向に導くことができますか?ありがとう。

+0

Googleでは、あなたの問題に関して多くの回答があります:) – RobinHood

答えて

0

でデコード//デコード画像サイズまたは//。 decodeStreamは、入力ストリームを使用している一定の期間が経過した後にnullを返します。

+0

私はあなたのメソッドを試してみましたが、動作しているようですが、画像全体をダウンロードしてバイト配列に入れるのはちょっと心配です。大量の画像が同時にダウンロードされている場合は、メモリを増やしてください。 –

+0

どちらの方法でも、完全なイメージをダウンロードする必要があります。デコードには完全な画像データが必要です。しかし、あなたのメソッドのために、メソッドはタイムアウトが発生すると失敗します。この期間に完全な画像データがロードされていない間は、一定の時間待機してヌル値を返します。より良い方法は、サーバーで画像を拡大/縮小することです。 – Shaiful

+0

それは意味があります。しかし、今私は画像をダウンサンプリングして、キャッシュに保存することができます。これは、サイズに応じてフル画像ではなく、以前よりもうまくいけば、少しのメモリを節約できます。私はそれがサーバー側を拡大する方が良いと同意します。 –

0

一度にダウンロードする画像の数を確認してください。どのくらいの量のメモリを消費するかは、ほとんどのアンドロイド携帯電話で16MBという最大のヒープメモリがあります。リソースが必要ない場合は、通常の時間に解放(ヌル)してください。ヒープメモリが増え、メモリリークの問題は発生しません。これは、マルチメディアを扱うなどの高メモリアプリケーションの共通の問題の1つです。だからあなたがする必要があるのは、未使用のリソースをチェックし、将来使用するつもりではなく、それらをヌル(たとえばビットマップ)にすることなので、メモリを解放します。

+0

オリジナルのImageDownloaderソースからわかるように、ビットマップはSoftReferenceキャッシュにラップされているため、メモリが不足しているとガベージコレクションされるはずです?問題は、最初に大きすぎる画像をダウンロードしているので、ケースをダウンサンプリングする必要があることです。 –

+0

SDカードに保存しているのか、アプリケーションにのみ保存していますか? –

0

BitmapFactory.Optionsを使用してください。メモリが足りなくなったら、変数を削除してメモリをクリアしてみてください。

そして、あなたは「SkImageDecoderを::工場はnullを返し、」取得している最初の画像をダウンロードして、バイト配列に入れinSampleSize

+0

inSampleSizeのデコードで –

関連する問題