2013-03-20 3 views
2

크기가 1948X674이고 크기가 104kb 인 이미지가 하나 있습니다. Samsung Galaxy S3에서 OutOfMemoryError를 제공합니다. 가로 스크롤보기에서이 이미지를 표시하고 있습니다. 은 여기 내 XML힙 크기 증가 및 OutOf 메모리 오류 증가

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context=".Panorama" > 

    <HorizontalScrollView 
     android:id="@+id/hscroll" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:layout_above="@+id/tapToEnter" 
     android:scrollbars="none" > 

     <ImageView 
      android:id="@+id/imgPanorama" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" /> 
    </HorizontalScrollView> 

    <Button 
     android:id="@+id/tapToEnter" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:text="Tap to enter" /> 

</RelativeLayout> 

내가 프로그래밍 방식으로 여기에 이미지를 설정하고있다. decodeSampledBitmapFromResource() Loading Large Bitmap Efficiently에서 사용하고 있습니다.

Bitmap bmp; 
try 
     { 
     BitmapDrawable bd=(BitmapDrawable)getResources().getDrawable(R.drawable.panorama); 
     reqwidth=bd.getIntrinsicWidth(); 
     reqheight = bd.getIntrinsicHeight(); 
     }catch(OutOfMemoryError oom) 
     { 
      oom.printStackTrace(); 
     } 
bmp=decodeSampledBitmapFromResource(getResources(),R.drawable.panorama, reqwidth, reqheight); 
imgPanorama.setImageBitmap(bmp); 




public static int calculateInSampleSize(
      BitmapFactory.Options options, int reqWidth, int reqHeight) { 
     // Raw height and width of image 
     final int height = options.outHeight; 
     final int width = options.outWidth; 
     int inSampleSize = 1; 


     if (height > reqHeight || width > reqWidth) { 

      // Calculate ratios of height and width to requested height and width 
      final int heightRatio = Math.round((float) height/(float) reqHeight); 
      final int widthRatio = Math.round((float) width/(float) reqWidth); 

      // Choose the smallest ratio as inSampleSize value, this will guarantee 
      // a final image with both dimensions larger than or equal to the 
      // requested height and width. 
      inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
     } 

     return inSampleSize; 
    } 
    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
      int reqWidth, int reqHeight) { 

     // First decode with inJustDecodeBounds=true to check dimensions 
     final BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 
     options.inPurgeable=true; 
     /*options.inDither=false;      //Disable Dithering mode 
     options.inPurgeable=true;     //Tell to gc that whether it needs free memory, the Bitmap can be cleared 
     options.inInputShareable=true;    //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future 
     options.inTempStorage=new byte[32 * 1024]; 
     */ 
     BitmapFactory.decodeResource(res, resId, options); 

     // Calculate inSampleSize 
     options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

     // Decode bitmap with inSampleSize set 
     options.inJustDecodeBounds = false; 
     return BitmapFactory.decodeResource(res, resId, options); 
    } 


@Override 
    protected void onDestroy() { 
     // TODO Auto-generated method stub 
     super.onDestroy(); 
     if(bmp!=null && !bmp.isRecycled()) 
     { 
      bmp.recycle(); 
      bmp=null; 

     } 
    } 

여기 활동을 시작할 때 내 logcat입니다. 이 이미지의 픽셀 데이터가 같은 일을 할 것입니다 수동 또는 자동 가비지 컬렉션보다 훨씬 더 빨리 해제 될 수 있기 때문에

03-20 11:20:36.175: I/dalvikvm-heap(30452): Grow heap (frag case) to 17.982MB for 5251824-byte allocation 
03-20 11:20:36.260: I/dalvikvm-heap(30452): Grow heap (frag case) to 38.014MB for 21007248-byte allocation 
03-20 11:20:36.385: I/dalvikvm-heap(30452): Grow heap (frag case) to 38.016MB for 5251824-byte allocation 
03-20 11:20:36.480: I/dalvikvm-heap(30452): Grow heap (frag case) to 58.050MB for 21007248-byte allocation 

답변

2

Bitmap.recycle()은 당신의 친구입니다. 따라서 큰 이미지가 완성되면 범위를 벗어나기 전에 recycle()에 좋은 아이디어가 될 수 있습니다. 물론 범위를 벗어나면 자동으로 가비지 수집되지만 recycle()Bitmap에서 사용되는 대부분의 메모리를 즉시 해제합니다.

예를 들어, 당신은 UI 요소에 Bitmap를 복사 한 후 recycle() 선택할 수 있도록하는

Bitmap bmp; 
bmp=decodeSampledBitmapFromResource(getResources(),R.drawable.panorama, reqwidth, reqheight); 
imgPanorama.setImageBitmap(bmp); 

// Free the pixel data immediately in order to keep heap from growing out of control. 
// This is especially useful while displaying multiple images. 
bmp.recycle(); 

또한 reqwidthreqheight의 작은 값을 실험 할 수 있습니다 더 큰 그래서 inSampleSize을 계산하여 Bitmap 그 훨씬 적은 메모리를 사용합니다.

+0

잘 말씀 드렸듯이 리사이클 비트 맵을 사용해 보았습니다. 그것은 이미 재활용 된 비트 맵을 사용할 수없는 것처럼 오류를줍니다. – Manoj

+0

'bmp.recycle()'호출 후에 'getWidth()'및 'getHeight()'와 같은 비 픽셀 액세스 함수를 제외하고 'bmp'이미지를 사용할 수 없습니다. 'setImageBitmap) '를 호출 한 다음'bmp.recycle() '호출을 이동하십시오. –

+0

당신은 바로 높이와 너비 함수를 사용하고 있었다 위의 코드를 참조하십시오. 나는 Destroy()에서 그것을 재활용했다. – Manoj