http://blog.csdn.net/quan648997767/article/details/11560415
       
      最近因为项目里需求是选择或者拍摄多张照片后,提供滑动预览和上传,很多照片是好几MB一张,因为目前的Android系统对运行的程序都有一定的内存限制,一般是16MB或24MB(视平台而定),不做处理直接加载的话必然会报OOM 
      (Out Of 
      Memmory)。网上有很多解决android加载bitmap内存溢出的方法,我总结了一个通用的方法,下面是我从的开发案例抽取出来的代码:
       
      我在项目中建了个Util.java工具类,里面写了个方法,根据图片的路径返回一个字节流数组对象:
       
       
      
      
      
        - public static byte[] decodeBitmap(String path) {  
-         BitmapFactory.Options opts = new BitmapFactory.Options();  
-         opts.inJustDecodeBounds = true;  
-         BitmapFactory.decodeFile(path, opts);  
-         opts.inSampleSize = computeSampleSize(opts, -1, 1024 * 800);  
-         opts.inJustDecodeBounds = false;  
-         opts.inPurgeable = true;  
-         opts.inInputShareable = true;  
-         opts.inDither = false;  
-         opts.inPurgeable = true;  
-         opts.inTempStorage = new byte[16 * 1024];  
-         FileInputStream is = null;  
-         Bitmap bmp = null;  
-         ByteArrayOutputStream baos = null;  
-         try {  
-             is = new FileInputStream(path);  
-             bmp = BitmapFactory.decodeFileDescriptor(is.getFD(), null, opts);  
-             double scale = getScaling(opts.outWidth * opts.outHeight,  
-                     1024 * 600);  
-             Bitmap bmp2 = Bitmap.createScaledBitmap(bmp,  
-                     (int) (opts.outWidth * scale),  
-                     (int) (opts.outHeight * scale), true);  
-             bmp.recycle();  
-             baos = new ByteArrayOutputStream();  
-             bmp2.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
-             bmp2.recycle();  
-             return baos.toByteArray();  
-         } catch (FileNotFoundException e) {  
-             e.printStackTrace();  
-         } catch (IOException e) {  
-             e.printStackTrace();  
-         } finally {  
-             try {  
-                 is.close();  
-                 baos.close();  
-             } catch (IOException e) {  
-                 e.printStackTrace();  
-             }  
-             System.gc();  
-         }  
-         return baos.toByteArray();  
-     }  
-   
-     private static double getScaling(int src, int des) {  
-          
-  
-   
-         double scale = Math.sqrt((double) des / (double) src);  
-         return scale;  
-     }  
-   
-     public static int computeSampleSize(BitmapFactory.Options options,  
-             int minSideLength, int maxNumOfPixels) {  
-         int initialSize = computeInitialSampleSize(options, minSideLength,  
-                 maxNumOfPixels);  
-   
-         int roundedSize;  
-         if (initialSize <= 8) {  
-             roundedSize = 1;  
-             while (roundedSize < initialSize) {  
-                 roundedSize <<= 1;  
-             }  
-         } else {  
-             roundedSize = (initialSize + 7) / 8 * 8;  
-         }  
-   
-         return roundedSize;  
-     }  
-   
-     private static int computeInitialSampleSize(BitmapFactory.Options options,  
-             int minSideLength, int maxNumOfPixels) {  
-         double w = options.outWidth;  
-         double h = options.outHeight;  
-   
-         int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math  
-                 .sqrt(w * h / maxNumOfPixels));  
-         int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(  
-                 Math.floor(w / minSideLength), Math.floor(h / minSideLength));  
-   
-         if (upperBound < lowerBound) {  
-             return lowerBound;  
-         }  
-   
-         if ((maxNumOfPixels == -1) && (minSideLength == -1)) {  
-             return 1;  
-         } else if (minSideLength == -1) {  
-             return lowerBound;  
-         } else {  
-             return upperBound;  
-         }  
-     }  
 
      
       
      然后在我需要加载图片BitMap的地方来调用Util.decodeBitmap():
       
      
      
      
        - Bitmap bitmap = BitmapFactory.decodeByteArray(Util.decodeBitmap(imagePath), 0, Util.decodeBitmap(imagePath).length);  
-                 imageCache.put(imagePath, new SoftReference<Bitmap>(bitmap));  
 
       
       
      
      
上面这两行是我的AsyncImageLoaderByPath类中的代码,用来加载SD卡里面的图片,该类完整代码是:
       
      
      
      
        - package com.pioneer.travel.util;  
-   
- import java.io.IOException;  
- import java.io.InputStream;  
- import java.lang.ref.SoftReference;  
- import java.net.MalformedURLException;  
- import java.net.URL;  
- import java.util.HashMap;  
-   
- import android.content.Context;  
- import android.graphics.Bitmap;  
- import android.graphics.BitmapFactory;  
- import android.graphics.BitmapFactory.Options;  
- import android.graphics.drawable.Drawable;  
- import android.os.Handler;  
- import android.os.Message;  
- import android.provider.MediaStore;  
- import android.util.Log;  
- import android.widget.ImageView;  
-   
- public class AsyncImageLoaderByPath {  
-       
-     private HashMap<String, SoftReference<Bitmap>> imageCache;  
-     private Context context;  
-       
-     public AsyncImageLoaderByPath(Context context) {  
-         this.imageCache = new HashMap<String, SoftReference<Bitmap>>();  
-         this.context = context;  
-     }  
-     public Bitmap loadBitmapByPath(final String imagePath, final ImageView imageView, final ImageCallback imageCallback){  
-         if (imageCache.containsKey(imagePath)) {  
-               
-             SoftReference<Bitmap> softReference = imageCache.get(imagePath);  
-             Bitmap bitmap = softReference.get();  
-             if (bitmap != null) {  
-                 return bitmap;  
-             }  
-         }  
-         final Handler handler = new Handler() {  
-             public void handleMessage(Message message) {  
-                 imageCallback.imageLoaded((Bitmap) message.obj, imageView, imagePath);  
-             }  
-         };  
-           
-         new Thread() {  
-             @Override  
-             public void run() {  
-                 Bitmap bitmap = BitmapFactory.decodeByteArray(Util.decodeBitmap(imagePath), 0, Util.decodeBitmap(imagePath).length);  
-                 imageCache.put(imagePath, new SoftReference<Bitmap>(bitmap));  
-                 Message message = handler.obtainMessage(0, bitmap);  
-                 handler.sendMessage(message);  
-             }  
-         }.start();  
-         return null;  
-     }  
-       
-     public interface ImageCallback {  
-         public void imageLoaded(Bitmap imageBitmap,ImageView imageView, String imagePath);  
-     }  
- }  
 
      
       
      通过这个实例,我验证了一下,一次性获取20张5MB的照片,都可以加载的很流畅,完全没有再出现报OOM的错误了
      以下是运行效果
      SD卡中的图片:
      
       
彻底解决Android因加载多个大图引起的OutOfMemoryError,内存溢出的问题,布布扣,bubuko.com
彻底解决Android因加载多个大图引起的OutOfMemoryError,内存溢出的问题
原文:http://www.cnblogs.com/leaven/p/3633355.html