2013-03-20 4 views
2

У меня есть одно изображение размером 1948X674 и размером 104kb. Это дает OutOfMemoryError на Samsung Galaxy S3. Я показываю это изображение в горизонтальном прокрутке. Вот мой XMLРост размера кучи и ошибка OutOfMemory

<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; 

     } 
    } 

Вот мой логарифм, когда я начинаю деятельность.

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.

Например, вы можете выбрать recycle() после копирования Bitmap на UI элемента:

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(); 

Вы также можете экспериментировать с меньшими значениями reqwidth и reqheight, что позволит больше рассчитывается inSampleSize так, что ваш Bitmap будет использовать значительно меньше памяти.

+0

хорошо пробовал переработку растрового изображения, как вы сказали. он дает ошибку, как нельзя использовать битмап, который уже переработан. – Manoj

+0

Изображение «bmp» не может использоваться после вызова «bmp.recycle()», за исключением непиксельных функций доступа, таких как «getWidth()» и «getHeight()» и т. Д. Если он используется после «setImageBitmap () ', затем переместите вызов bmp.recycle(). –

+0

Вы были правы, я использовал функции высоты и ширины, см. Код выше. Я переработал его в Destroy(). – Manoj

Смежные вопросы