在Android中,對圖片使用的內存是有限制的,加載的圖片過大便出導致OOM問題。圖像在加載過程中,是把所有像素(即長*寬)加載到內存中,如果圖片過大,便會導致java.lang.OutOfMemoryError問題,因此,在使用時要要加以注意。
- private static int MAX_IMAGE_DIMENSION = 720;
- public Bitmap decodeFile(String filePath) throws IOException {
- Uri photoUri = Uri.parse(filePath);
- InputStream is = this.getContentResolver().openInputStream(photoUri);
- BitmapFactory.Options dbo = new BitmapFactory.Options();
- dbo.inJustDecodeBounds = true;
- BitmapFactory.decodeStream(is, null, dbo);
- is.close();
- int rotatedWidth, rotatedHeight;
- rotatedWidth = dbo.outWidth;
- rotatedHeight = dbo.outHeight;
- Bitmap mCurrentBitmap = null;
- is = this.getContentResolver().openInputStream(photoUri);
- if (rotatedWidth > MAX_IMAGE_DIMENSION || rotatedHeight > MAX_IMAGE_DIMENSION) {
- float widthRatio = ((float) rotatedWidth) / MAX_IMAGE_DIMENSION;
- float heightRatio = ((float) rotatedHeight) / MAX_IMAGE_DIMENSION;
- float maxRatio = Math.max(widthRatio, heightRatio);
- // Create the bitmap from file
- BitmapFactory.Options options = new BitmapFactory.Options();
- // 1.換算合適的圖片縮放值,以減少對JVM太多的內存請求。
- options.inSampleSize = (int) maxRatio;
- // 2. inPurgeable 設定爲 true,可以讓java系統, 在內存不足時先行回收部分的內存
- options.inPurgeable = true;
- // 與inPurgeable 一起使用
- options.inInputShareable = true;
- // 3. 減少對Aphla 通道
- options.inPreferredConfig = Bitmap.Config.RGB_565;
- try {
- // 4. inNativeAlloc 屬性設置爲true,可以不把使用的內存算到VM裏
- BitmapFactory.Options.class.getField("inNativeAlloc").setBoolean(options, true);
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- }
- // 5. 使用decodeStream 解碼,則利用NDK層中,利用nativeDecodeAsset()
- // 進行解碼,不用CreateBitmap
- mCurrentBitmap = BitmapFactory.decodeStream(is, null, options);
- } else {
- mCurrentBitmap = BitmapFactory.decodeStream(is);
- }
- return mCurrentBitmap;
- }