2013-05-21 38 views
1
我有我的VSD220一個OutOfMemoryError

(這是一個22" 基於Android的All in one的)Android的位圖的OutOfMemoryError

for (ImageView img : listImages) { 
      System.gc(); 

      Bitmap myBitmap = BitmapFactory.decodeFile(path); 
      img.setImageBitmap(myBitmap); 
      img.setOnClickListener(this); 
     } 

我真的不知道該怎麼辦,因爲這個形象是最大的下方分辨率,圖像尺寸是一些關於(1000×1000),顯示這是1920×1080。

任何幫助嗎? (這的foreach循環是約20元,但後6 GOTS打破,或7圈..)

非常感謝。

Ezequiel。

+0

我不同意將此標記爲重複。在這個問題中,同一個圖像被重複加載到一個循環中。即使圖像非常小,如果迭代次數足夠高,您會發現內存不足錯誤。 – britzl

回答

0

您確定要加載相同的位圖20次嗎?你不想加載一次並將其設置在循環中。

不管怎樣,無論屏幕分辨率如何,加載1000x1000像素的圖像都無法保證正常工作。請記住,1000x1000像素的圖片佔用1000x1000x4字節=〜4MB(如果您將其加載爲ARGB_8888)。如果堆內存碎片/太小,則可能沒有足夠的空間來加載位圖。你可能想看看進入BitmapFactory.Options類以及inPreferredConfiginSampleSize實驗

我會建議你通過DigCamara使用的建議,並決定在大小和負載接近該尺寸的下采樣圖像(我說的差不多,因爲你將不會使用該技術得到確切的大小),或者您嘗試加載完整大小的圖像,然後遞歸增加樣本大小(通過兩個因子獲得最佳結果),直到您達到最大樣本大小或圖像加載:

/** 
* Load a bitmap from a stream using a specific pixel configuration. If the image is too 
* large (ie causes an OutOfMemoryError situation) the method will iteratively try to 
* increase sample size up to a defined maximum sample size. The sample size will be doubled 
* each try since this it is recommended that the sample size should be a factor of two 
*/ 
public Bitmap getAsBitmap(InputStream in, BitmapFactory.Config config, int maxDownsampling) { 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inSampleSize = 1; 
    options.inPreferredConfig = config; 
    Bitmap bitmap = null; 
    // repeatedly try to the load the bitmap until successful or until max downsampling has been reached 
    while(bitmap == null && options.inSampleSize <= maxDownsampling) { 
     try { 
      bitmap = BitmapFactory.decodeStream(in, null, options); 
      if(bitmap == null) { 
       // not sure if there's a point in continuing, might be better to exit early 
       options.inSampleSize *= 2; 
      } 
     } 
     catch(Exception e) { 
      // exit early if we catch an exception, for instance an IOException 
      break; 
     } 
     catch(OutOfMemoryError error) { 
      // double the sample size, thus reducing the memory needed by 50% 
      options.inSampleSize *= 2; 
     } 
    } 
    return bitmap; 
} 
+0

對不起,我不想加載相同的圖像20次,我想簡化這個例子,我的真實代碼由一組路徑組成。所以圖像是不一樣的,但尺寸是。 我正在嘗試你的答案,現在的傢伙。 我會在此之後再發表評論。 非常感謝! –

+0

非常感謝你。 它適用於這個縮略圖,現在我必須顯示一個全屏圖像(在這種情況下爲1920x1024),並製作它們的圖庫。我會盡力做到這一點閱讀Android位圖部分! http://developer.android.com/training/displaying-bitmaps/index。html –

1

你應該看看培訓文檔Managing Bitmap Memory。根據您的操作系統版本,您可以使用不同的技術來管理更多的位圖,但您可能必須改變您的代碼。

特別是,你很可能將在「Load a Scaled Down Version into Memory」使用的代碼的修改版本,但我至少發現這部分特別有用:

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

這方法可以很容易地任意大尺寸 的位圖加載到一個顯示100×100像素的縮略圖的ImageView的,如在 所示的以下示例代碼:

mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100)); 
+0

try { //此處導致OutOfMemoryError的代碼 } catch(Error ee){ \t ee.printStacktrace(); } –