android報錯記錄及解決–Bitmap加載時,報bitmap size exceeds VM budget

報錯描述:

 

  用Bitmap加載圖片資源時,報錯java.lang.OutOfMemoryError: bitmap size exceeds VM budget

 

原因分析:

 

  android系統限制,隻給圖片分配8M內存,超過就蹦。圖片雖然幾十K,可能是壓縮格式,轉換成BitMap就是本來大小

 

解決辦法:

 

  1、Android模擬器在設置時可以將Max VM application heap size值設大一點,我這裡默認是16,改到60

 

    

 

  2、圖形對象優化,這裡要說的是Android上的Bitmap對象銷毀,可以借助recycle()方法顯示讓GC回收一個Bitmap對象,

 

     通常對一個不 用的Bitmap可以使用下面的方式,如 

 

  

 

1 if(bitmapObject.isRecycled()==false) //如果沒有回收  

2          bitmapObject.recycle();  

延伸學習:

 

  設置恰當的inSampleSize可以使BitmapFactory分配更少的空間以消除該錯誤,我們要將圖片按照固定大小取縮略圖,一般取縮略圖的方法是使用      BitmapFactory的decodeFile方法,然後通過傳遞進去 BitmapFactory.Option類型的參數進行取縮略圖,在Option中,屬性值inSampleSize表示縮略圖大小為原始圖片大小的幾分之一,即如果這個值為2,則取出的縮略圖的寬和高都是原始圖片的1/2,圖片大小就為原始大小的1/4

 

1         BitmapFactory.Options opts =  new  BitmapFactory.Options();

2         opts.inSampleSize =  4 ;

3         Bitmap bitmap = BitmapFactory.decodeFile(imageFile, opts);

  然而,如果我們想取固定大小的縮略圖就比較困難瞭,比如,我們想將不同大小的圖片去出來的縮略圖高度都為200px,而且要保證圖片不失真,那怎麼辦?我們總不能將原始圖片加載到內存中再進行縮放處理吧,要知道在移動開發中,內存是相當寶貴的,而且一張100K的圖片,加載完所占用的內存何止 100K?

 

  可以通過設置Options中有個屬性inJustDecodeBounds來處理,如果該值設為true那麼將不返回實際的bitmap不給其分配內存空間而裡面隻包括一些解碼邊界信息即圖片大小信息,那麼相應的方法也就出來瞭,通過設置inJustDecodeBounds為true,獲取到outHeight(圖片原始高度)和 outWidth(圖片的原始寬度),然後計算一個inSampleSize(縮放值),然後就可以取圖片瞭,這裡要註意的是,inSampleSize 可能小於0,必須做判斷。

 

復制代碼

 1 BitmapFactory.Options options = new BitmapFactory.Options();

 2         options.inJustDecodeBounds = true;

 3         // 獲取這個圖片的寬和高

 4         Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/test.jpg", options); //此時返回bm為空

 5         options.inJustDecodeBounds = false;

 6          //計算縮放比

 7         int be = (int)(options.outHeight / (float)200);

 8         if (be <= 0)

 9             be = 1;

10         options.inSampleSize = be;

11         //重新讀入圖片,註意這次要把options.inJustDecodeBounds 設為 false哦

12         bitmap=BitmapFactory.decodeFile("/sdcard/test.jpg",options);

13         int w = bitmap.getWidth();

14         int h = bitmap.getHeight();

15         System.out.println(w+"   "+h);

16         ImageView iv=new ImageView(this);

17         iv.setImageBitmap(bitmap);

復制代碼

這樣我們就可以讀取較大的圖片而不會內存溢出瞭。

發佈留言