Android內存溢出OutOfMemoryError

最近做android的項目,碰到一個下載圖片并顯示的需求,當下載的圖片較多時,出現OutOfMemoryError的異常。

試了好多優化方式,最后發現是因為圖片比較大時,bitmap分配內存溢出問題。最后總結了一下,優化的方式有下面幾種:

1、不用的bitmap要及時回收銷毀

??? bitmap.recycle();bitmap= null;

2、顯示調用system.gc();觸發垃圾回收,及時回收內存。

3、stream轉換為bitmap時壓縮圖片質量

??? 我的問題是BitmapFactory.decodeStream(stream)這個方法報的錯誤,錯誤信息是OutOfMemoryError。

??? 也就是說stream轉換為bitmap的時候內存不夠。下面是我的解決方案:

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

??? options.inJustDecodeBounds = true;

??? Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);

??? int imageHeight = options.outHeight;

??? int imageWidth = options.outWidth;

??? if(imageWidth > 200)

??? {

??????? int maxpix = imageHeight > imageWidth ? imageHeight : imageWidth;

??????? int scale = (int) (maxpix / 100);

??????? if (scale <= 0)

??????? {

??????????? scale = 1;

??????? }

??????? options.inSampleSize = scale;

??? }

??? options.inJustDecodeBounds = false;

??? stream = image.getImageViewInputStream(imageUrl);//重新讀取stream

??? bitmap = BitmapFactory.decodeStream(stream,null,options);


??? 屬性inJustDecodeBounds設置為true時,返回的bitmap為空,只是讀取圖片信息,

??? 并不使用內存讀取bitmap,當inJustDecodeBounds設置為false時,讀取bitmap,

??? 這之前必須重新讀一下stream。

4、壓縮圖片的其他方式

??? 1> 按寬高比縮放

??? public static Bitmap zoomImage(Bitmap bgimage, double newWidth,? double newHeight) {

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

??? float width = bgimage.getWidth();

??? float height = bgimage.getHeight();

??? // 創建操作圖片用的matrix對象

??? Matrix matrix = new Matrix();

??? // 計算寬高縮放率

??? float scaleWidth = ((float) newWidth) / width;

??? float scaleHeight = ((float) newHeight) / height;

??? // 縮放圖片動作

??? matrix.postScale(scaleWidth, scaleHeight);

??? Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,

??? (int) height, matrix, true);

??? return bitmap;

??? }

2> 壓縮大小最大100k

??? public static Bitmap GetPressBitmap(Bitmap bitMap)

??? {

??? double maxSize = 100;

??? //將bitmap放至數組中,意在bitmap的大小(與實際讀取的原文件要大)

??? ByteArrayOutputStream baos = new ByteArrayOutputStream();

??? bitMap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

??? byte[] b = baos.toByteArray();

??? //將字節換成KB

??? double mid = b.length/1024;

??? //判斷bitmap占用空間是否大于允許最大空間? 如果大于則壓縮 小于則不壓縮

??? if (mid > maxSize) {

??????? //獲取bitmap大小 是允許最大大小的多少倍

? ? ? ? double i = mid / maxSize;

?? ? ?? //開始壓縮? 此處用到平方根 將寬帶和高度壓縮掉

? ?? ?? //對應的平方根倍 (1.保持刻度和高度和原bitmap

? ?? ?? //比率一致,壓縮后也達到了最大大小占用空間的大小)

? ?? ?? bitMap = zoomImage(bitMap, bitMap.getWidth() / Math.sqrt(i),

? ?? ?? bitMap.getHeight() / Math.sqrt(i));

??? }

??? return bitMap;

??? }

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容