2012-03-10 4 views
0

내가 사람의 검색 키가 주어 안드로이드에서 연락처의 사진을 검색하기 위해 다음과 같은 기능을 사용하여 안드로이드에 연락처의 사진을 표시 할 때 :OutOfMemoryError를 (비트 맵의 ​​크기는 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메가바이트했다 내 애플 힙의 3메가바이트하지만 하나의 비트 맵에 대해 사용할 수 있다는 뜻

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

    당신이 설정하는 당신의 BitmapImageView에, 시도는이 일을 : 그것은이 제거 완료되지 않을

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

    문제는 아니지만 확실히 드물게 발생합니다.

    +0

    고마워요! 이것을 구현하려고 시도했을 때 imageView.getDrawable()의 결과에는 getBitmap() 메서드가 없습니다. 또한, 내 경우에 단일 비트 맵이 너무 큽니다 오류가 아닌가요? – caw

    +0

    'BitmapDrawable'으로 캐스팅해야합니다. 이'ImageView's에'Bitmap's을 설정하면 안전한 캐스트입니다. 또한 기본 문제의 메모리가 부족할 수도 있습니다. 때로는 이러한 오류가기만적인 경우가 있습니다. 그럴만 한 가치가있는 것은 좋은 행동입니다. –

    +0

    감사합니다. 이제 작동합니다! 불행히도 다음과 같은 런타임 예외가 발생합니다. "캔버스 : 재활용 된 비트 맵을 사용하려고합니다." 따라서 어댑터 항목/행을 재활용하는 것이 해결책이 아닌 것 같습니다. – caw

    0

    비트 맵 크기 조정을 시도 했습니까? 다음은이 방법 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); 
         } 
    

    , 나는 그것이 이전보다 적은 메모리를 소모하도록 조정 Bitmap을 만들 ... 당신이 그것을 어떻게, 무슨 당신에 대한 내 문제를 해결?

    관련 문제