android加载图片时避免出现OOM(OutOfMemory)

时间:2021-09-14 22:40:11
一、利用BitmapFactory.Options在图片加载到内存前先进行压缩
相关API
    BitmapFactory.Options options = new BitmapFactory.Options();
//true:不返回bitmap对象,但可以获得宽高等属性
options.inJustDecodeBounds = true;
//将原图压缩成原来的1/4
options.inSampleSize = 4;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,int reqWidth, int reqHeight) {        // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小        final BitmapFactory.Options options = new BitmapFactory.Options();        options.inJustDecodeBounds = true;        BitmapFactory.decodeResource(res, resId, options);        // 调用上面定义的方法计算inSampleSize值        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);        // 使用获取到的inSampleSize值再次解析图片        options.inJustDecodeBounds = false;        return BitmapFactory.decodeResource(res, resId, options);    }    public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {        // 源图片的高度和宽度        final int height = options.outHeight;        final int width = options.outWidth;        int inSampleSize = 1;        if (height > reqHeight || width > reqWidth) {            // 计算出实际宽高和目标宽高的比率            final int heightRatio = Math.round((float) height / (float) reqHeight);            final int widthRatio = Math.round((float) width / (float) reqWidth);            // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高            // 一定都会大于等于目标的宽和高。            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;        }        return inSampleSize;    }

二、利用LruCache进行图片缓存
public class MyLruCache {
//android.support.v4.util.LruCache
private LruCache<String, Bitmap> mMemoryCache;

public MyLruCache(){
// 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。
// LruCache通过构造函数传入缓存值,以KB为单位。
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// 使用最大可用内存值的1/8作为缓存的大小。
int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// 重写此方法来衡量每张图片的大小,默认返回图片数量。
return bitmap.getByteCount() / 1024;
}
};
}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}

public Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}
}