首页 > 代码库 > 【转】解决Android因加载多个大图引起的OutOfMemoryError,内存溢出的问题

【转】解决Android因加载多个大图引起的OutOfMemoryError,内存溢出的问题

本文来自:http://blog.csdn.net/wulianghuan/article/details/11548373,感谢原作者的分享。

目标是读取SD卡中的图片并且展示出来

主要思路是通过一个工具类来压缩来自sd卡中的图片,最后通过缓存机制来避免占用过多内存。

Util.java

package com.kale.socketactivity;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import android.graphics.Bitmap;import android.graphics.BitmapFactory;public class Util {        /**     * @param path     * @return     * @example Bitmap bitmap = BitmapFactory.decodeByteArray(Util.decodeBitmap(imagePath), 0, Util.decodeBitmap(imagePath).length);                  imageCache.put(imagePath, new SoftReference<Bitmap>(bitmap));  //这里用了软引用     */    public static byte[] decodeBitmap(String path) {        BitmapFactory.Options opts = new BitmapFactory.Options();        opts.inJustDecodeBounds = true;// 设置成了true,不占用内存,只获取bitmap宽高        BitmapFactory.decodeFile(path, opts);        opts.inSampleSize = computeSampleSize(opts, -1, 1024 * 800);        opts.inJustDecodeBounds = false;// 这里一定要将其设置回false,因为之前我们将其设置成了true        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) {        /**         * 48 目标尺寸÷原尺寸 sqrt开方,得出宽高百分比 49         */        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 bitmap = BitmapFactory.decodeByteArray(Util.decodeBitmap(imagePath), 0, Util.decodeBitmap(imagePath).length);                  imageCache.put(imagePath, new SoftReference<Bitmap>(bitmap));  

 

实现类

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 {    //SoftReference是软引用,是为了更好的为了系统回收变量    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);            }        };        //建立新一个获取SD卡的图片        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);    }}

 

【转】解决Android因加载多个大图引起的OutOfMemoryError,内存溢出的问题