解决加载本地res图片oom终极方案
- 昨天拿了几张美女图放手机玩玩..发现划几下就崩了,肯定是oom…于是着手解决
- 之前一直很信赖xutils框架.毕竟开发大图基本是网络获取.小图直接设置,没多大问题…于是寻找xutils下是否有设置res的drable方法..然并软
于是就自己着手解决,大概思路就是老生常谈的加载缩略图
生成缩略图还未足够,如果每次都重新生成缩略图..这样将大大消耗内存..程序将变得很卡
于是写了个工具类..缓存加载
public static int maxMemory=0;//定义最大缓存大小 public static LruCache mMemoryCache;//一种缓存算法 /** * 防止oom解析图片 * @param res context.getresources * @param resId 图片的id * @param reqWidth 图片放到控件的宽 * @param reqHeight 图片放到控件的高 * @return */ public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { //判断最大缓存大小是否为零..如果为零则进行分配缓存 if (maxMemory==0){ //获取运行时候分配给应用的内存 maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); // 使用最大可用内存值的1/4作为缓存的大小。 int cacheSize = maxMemory /4; Yayalog.loger("应用最大的内存"+cacheSize); mMemoryCache = new LruCache<Integer, Bitmap>(cacheSize) { @Override protected int sizeOf(Integer key, Bitmap Bitmap) { Yayalog.loger("shenme"+Bitmap.getByteCount() / 1024); // 重写此方法来衡量每张图片的大小,默认返回图片数量。 return Bitmap.getByteCount() / 1024; } }; } //获取缓存中的图片 Bitmap bitmapFromMemCache = getBitmapFromMemCache(resId); Yayalog.loger(resId+"大小"+mMemoryCache.size()); if (bitmapFromMemCache==null){ // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小 final BitmapFactory.Options options = new BitmapFactory.Options(); //设置此参数true,将不会真正解析图片返回的值为空..次操作仅仅是将图片的宽高设置到options中,后面真正解析要改为flase options.inJustDecodeBounds = true; options.inPreferredConfig = Bitmap.Config.RGB_565; BitmapFactory.decodeResource(res, resId, options); // 调用上面定义的方法计算inSampleSize值 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 使用获取到的inSampleSize值再次解析图片 options.inJustDecodeBounds = false; Bitmap decodebitmap=BitmapFactory.decodeResource(res, resId, options); addBitmapToMemoryCache(resId, decodebitmap); return decodebitmap; }else { // Yayalog.loger("缓存的图片"); return bitmapFromMemCache; } } 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 = heightRatio < widthRatio ? heightRatio : widthRatio; } Yayalog.loger("图片宽度"+width+"图片高度"+height+"缩放比"+inSampleSize); // if (height > reqHeight || width > reqWidth) { return inSampleSize+1; }
具体使用
直接view.setxxxx(decodeSampledBitmapFromResource());
本文代码来源于网络,并非原创,仅仅是写了个方便自己使用的工具类.