Android 中 加載Bitmap

[轉]Android 中 加載Bitmap時,造成的Out of memory 問題


在Android中,對圖片使用的內存是有限制的,加載的圖片過大便出導致OOM問題。圖像在加載過程中,是把所有像素(即長*寬)加載到內存中,如果圖片過大,便會導致java.lang.OutOfMemoryError問題,因此,在使用時要要加以注意。



  1. private static int MAX_IMAGE_DIMENSION = 720;  
  2.   
  3.    public Bitmap decodeFile(String filePath) throws IOException {  
  4.   
  5.        Uri photoUri = Uri.parse(filePath);  
  6.        InputStream is = this.getContentResolver().openInputStream(photoUri);  
  7.        BitmapFactory.Options dbo = new BitmapFactory.Options();  
  8.        dbo.inJustDecodeBounds = true;  
  9.        BitmapFactory.decodeStream(is, null, dbo);  
  10.        is.close();  
  11.   
  12.        int rotatedWidth, rotatedHeight;  
  13.     rotatedWidth = dbo.outWidth;  
  14.        rotatedHeight = dbo.outHeight;  
  15.         
  16.   
  17.        Bitmap mCurrentBitmap = null;  
  18.        is = this.getContentResolver().openInputStream(photoUri);  
  19.        if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {  
  20.            float widthRatio = ((float) rotatedWidth) / MAX_IMAGE_DIMENSION;  
  21.            float heightRatio = ((float) rotatedHeight) / MAX_IMAGE_DIMENSION;  
  22.            float maxRatio = Math.max(widthRatio, heightRatio);  
  23.            // Create the bitmap from file  
  24.            BitmapFactory.Options options = new BitmapFactory.Options();  
  25.            // 1.換算合適的圖片縮放值,以減少對JVM太多的內存請求。  
  26.            options.inSampleSize = (int) maxRatio;  
  27.            // 2. inPurgeable 設定爲 true,可以讓java系統, 在內存不足時先行回收部分的內存  
  28.            options.inPurgeable = true;  
  29.            // 與inPurgeable 一起使用  
  30.            options.inInputShareable = true;  
  31.            // 3. 減少對Aphla 通道  
  32.            options.inPreferredConfig = Bitmap.Config.RGB_565;  
  33.            try {  
  34.                // 4. inNativeAlloc 屬性設置爲true,可以不把使用的內存算到VM裏  
  35.                BitmapFactory.Options.class.getField("inNativeAlloc").setBoolean(options, true);  
  36.            } catch (IllegalArgumentException e) {  
  37.                e.printStackTrace();  
  38.            } catch (SecurityException e) {  
  39.                e.printStackTrace();  
  40.            } catch (IllegalAccessException e) {  
  41.                e.printStackTrace();  
  42.            } catch (NoSuchFieldException e) {  
  43.                e.printStackTrace();  
  44.            }  
  45.            // 5. 使用decodeStream 解碼,則利用NDK層中,利用nativeDecodeAsset()  
  46.            // 進行解碼,不用CreateBitmap  
  47.            mCurrentBitmap = BitmapFactory.decodeStream(is, null, options);  
  48.        } else {  
  49.            mCurrentBitmap = BitmapFactory.decodeStream(is);  
  50.        }  
  51.        return mCurrentBitmap;  
  52.    }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章