【android】解決因為圖片太大引起的內存不足問題,Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget


這個問題很早就遇到了,當時怎么解決的忘記了。今天在做項目的時候又出現了。

我先是在我自己的Lenovo A750手機上調試沒問題,放到HTC的G18上報錯!放到電腦的2.2模擬器上報錯!這個問題一出現瞬間發狂了~

好吧,來了我就把它解決掉!

先看看我的問題出在哪里:

1         LayoutInflater inflater=getLayoutInflater(); 2         list=new ArrayList<View>(); 3         list.add(inflater.inflate(R.layout.item1, null));//就在這!
4         list.add(inflater.inflate(R.layout.item2, null)); 5         list.add(inflater.inflate(R.layout.item3, null)); 6         list.add(inflater.inflate(R.layout.item4, null));

我在每一個item中只加了一個imageview控件,圖片的src在xml中就定好了。在添加到list中的時候報錯了。

在網上找引起報錯的原因沒直接找到,但找到一個相關的:

“當圖片過大,或圖片數量較多時使用BitmapFactory解碼圖片會出java.lang.OutOfMemoryError: bitmap size exceeds VM budget,要想正常使用則需分配更少的內存,具體的解決辦法是修改采樣值BitmapFactory.Options.inSampleSize”

同樣的錯誤錯誤效果,他們出錯是在讀取圖片文件的時候報錯,看看自己的代碼,想要修改Options.inSampleSize要把每一個item中的imageview控件拿出來設置他們的setBackgroundDrawable。

如下:

 1         LayoutInflater inflater=getLayoutInflater();  2         list=new ArrayList<View>();  3         
 4         View view = inflater.inflate(R.layout.item1, null);  5         view.findViewById(R.id.well_item).setBackgroundDrawable(new BitmapDrawable(readBitMap(this.getApplicationContext(), R.drawable.b1)));  6  list.add(view);  7         
 8         View view2 = inflater.inflate(R.layout.item2, null);  9         view2.findViewById(R.id.well_item).setBackgroundDrawable(new BitmapDrawable(readBitMap(this.getApplicationContext(), R.drawable.b2))); 10  list.add(view2); 11         
12         View view3 = inflater.inflate(R.layout.item3, null); 13         view3.findViewById(R.id.well_item).setBackgroundDrawable(new BitmapDrawable(readBitMap(this.getApplicationContext(), R.drawable.b3))); 14  list.add(view3); 15         
16         View view4 = inflater.inflate(R.layout.item4, null); 17         view4.findViewById(R.id.imageView1).setBackgroundDrawable(new BitmapDrawable(readBitMap(this.getApplicationContext(), R.drawable.b4))); 18  list.add(view4); 19         

 

上面的readBitMap方法就是解決問題的關鍵: 

 1     public static Bitmap readBitMap(Context context, int resId){  2         BitmapFactory.Options opt = new BitmapFactory.Options();  3         opt.inPreferredConfig = Bitmap.Config.RGB_565;  4         opt.inPurgeable = true;  5         opt.inInputShareable = true;  6         opt.inSampleSize = computeSampleSize(opt, -1, 128*128);  //計算出圖片使用的inSampleSize
 7         opt.inJustDecodeBounds = false;  8         //獲取資源圖片 
 9         InputStream is = context.getResources().openRawResource(resId); 10         return BitmapFactory.decodeStream(is,null,opt); 11  } 12     
13     public static int computeSampleSize(BitmapFactory.Options options, 14             int minSideLength, int maxNumOfPixels) { 15         int initialSize = computeInitialSampleSize(options, minSideLength,maxNumOfPixels); 16 
17         int roundedSize; 18         if (initialSize <= 8 ) { 19             roundedSize = 1; 20             while (roundedSize < initialSize) { 21                 roundedSize <<= 1; 22  } 23         } else { 24             roundedSize = (initialSize + 7) / 8 * 8; 25  } 26 
27         return roundedSize; 28  } 29 
30     private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) { 31         double w = options.outWidth; 32         double h = options.outHeight; 33 
34         int lowerBound = (maxNumOfPixels == -1) ? 1 : 35                 (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels)); 36         int upperBound = (minSideLength == -1) ? 128 : 37                 (int) Math.min(Math.floor(w / minSideLength), 38                 Math.floor(h / minSideLength)); 39 
40         if (upperBound < lowerBound) { 41             // return the larger one when there is no overlapping zone.
42             return lowerBound; 43  } 44 
45         if ((maxNumOfPixels == -1) &&
46                 (minSideLength == -1)) { 47             return 1; 48         } else if (minSideLength == -1) { 49             return lowerBound; 50         } else { 51             return upperBound; 52  } 53     }

“他們還提供一個方法是Bitmap.recycle()方法來釋放位圖所占的空間,當然前提是位圖沒有被使用”。本次是在加載第一個的時候就已經報錯。不在考慮了額。

參考鏈接:http://www.cnblogs.com/xiyo/archive/2012/05/26/2519028.html

              http://blog.csdn.net/yangxyjd/article/details/6932989


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM