2012-03-10 15 views
0

私は人のルックアップキーが指定されたアンドロイドで連絡先の写真を取得するには、次の機能を使用します。のOutOfMemoryErrorのAndroidで連絡先の写真を表示する(ビットマップのサイズはVMの予算を超過)

public Bitmap getContactPhoto(String lookup_key) { 
    Uri lookUpUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookup_key); 
    Uri contentUri = ContactsContract.Contacts.lookupContact(ctx.getContentResolver(), lookUpUri); 
    InputStream stream = null; 
    try { 
     stream = ContactsContract.Contacts.openContactPhotoInputStream(ctx.getContentResolver(), contentUri); 
    } 
    catch (Exception e) { 
    } 
    if (stream != null) { 
     return BitmapFactory.decodeStream(stream, null, bitmapOptions); 
    } 
    else { 
     return null; 
    } 
} 

私はそれらの連絡先を表示する場合これはおよそ27メガバイトを持っていた私のアプリは、ヒープ3MBのが、単一のビットマップについて使用できることを意味してい

Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=6023KB, Allocated=3002KB, Bitmap Size=27152KB) 

:リストビューの写真は、私は時々デベロッパーコンソールのクラッシュレポートに次のエラーを読んで?

私はのOutOfMemoryエラーについて、ここでスタックオーバーフローに関する質問をたくさん読んで、それは約主だった:ガベージコレクタがリソースをスケーリングする必要がある

  • 巨大なビットマップを解放することができないようにコンテキストをリーク

    私のケースではどのようにエラーを防ぐことができますか?私は連絡先の写真を取得するだけなので、スケーリングしなければならない巨大なビットマップがあるかどうかはわかりません。文脈を漏らすことは、ここではそうではないようです。

    これは、画像が表示されている方法です。

    imageView.setVisibility(View.VISIBLE); 
    imageView.setBackgroundResource(R.drawable.background); 
    if (<BITMAP_OBJECT> != null) { 
        imageView.setImageBitmap(<BITMAP_OBJECT>); 
    } 
    else { 
        imageView.setImageBitmap(null); 
    } 
    
  • +0

    問題はあなたが表示しているものとは関係ありません。 getContactPhoto()が – Blackbelt

    +0

    と呼ばれる場所にコードを添付してください申し訳ありませんが、これを今追加しました。 – caw

    +0

    あなたは何らかの種類のアダプタで投稿した最後のスニペットを呼び出しますか? – Blackbelt

    答えて

    2

    あなたがImageViewにごBitmapを設定している場合は、これをやってみてください:

    Bitmap oldBitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); 
    imageView.setImageDrawable(null); 
    oldBitmap.recycle(); 
    imageView.setImageBitmap(newBitmap); 
    

    それは取り除くを完了しない場合があります問題はありますが、それは確かに起こることはめったにありません。

    +0

    ありがとう!これを実装しようとすると、imageView.getDrawable()の結果にgetBitmap()メソッドがありません。また、単一のビットマップが大きすぎるという私の場合のエラーではありませんか? – caw

    +0

    これを 'BitmapDrawable'にキャストする必要があります。これらの 'ImageView'に' Bitmap'を設定しているのなら、それは安全なキャストです。 また、根底にある問題のメモリが不足している可能性があります。時々、これらのエラーは欺瞞的です。いずれにせよ、価値があるのは良いことです。 –

    +0

    ありがとう、今それは動作します!残念ながら、次のランタイム例外が発生します。「キャンバス:リサイクルされたビットマップを使用しようとしています。したがって、アダプタのエントリ/行をリサイクルすることは解決策ではないようです。 – caw

    0

    ビットマップの拡大縮小を試しましたか?それが以前より低いメモリを消費するようにここで私はスケールBitmapを作成し、...あなたはそれを行う方法ここでは方法BitmapFactory.decodeFile

    BitmapFactory.Options options = new BitmapFactory.Options(); 
        options.inJustDecodeBounds = true; 
        BitmapFactory.decodeFile(filename, options); 
         options.inJustDecodeBounds = false; 
         options.inSampleSize = 2; // adjust sample size to whatever you want it to be 
    
         bitmap = BitmapFactory.decodeFile(filename, options); 
         if (bitmap != null && exact) { 
          bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false); 
         } 
    

    あり、それはどのようなあなたについて、私の問題を解決しましたか?

    関連する問題