您的位置:首页 > 其它

个人浅谈OOM

2015-10-15 17:31 393 查看
关于Android中的OOM,一般情况下是由图片所导致的,所以今天就谈谈我的学习总结:

情况1:是由单个图片过大超出了系统为之分配的内存所引起的。

而我的解决办法就是 压缩图片

压缩图片比较多的方法有三种(我所用的)

(1) 图片按比例大小压缩方法(根据Bitmap图片压缩)

(2) 质量压缩法

(3) 图片按比例大小压缩方法(根据路径获取图片并压缩)

好了,开始码上我的代码:

(1) 图片按比例大小压缩方法(根据Bitmap图片压缩)

//第一步 创建一个BitmapFactory.Options

BitmapFactory.Options options = new BitmapFactory.Options();

//第二步 设置inJustDecodeBounds 为true

options.inJustDecodeBounds = true;

//第三步 加载需要压缩的图片

BitmapFactory.decodeResource(getResources(),R.mipmap.netc,options);

// 第四步 获得图片大小

int width = options.outWidth;

int height = options.outHeight;

String info = "宽:"+width +" 高:"+height;

Log.v("MainAcitity", info);

//第五步 获取屏幕大小

DisplayMetrics dm = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(dm);

int screenWidth = dm.widthPixels;

int screenHeight =dm.heightPixels;

String screeninfo = "屏幕宽:"+screenWidth +" 屏幕高:"+screenHeight;

Log.v("MainActivity",screeninfo);

//第六步 计算真实图片与屏幕分辨率的比率

int widthSample = width/screenWidth;

int heightSample = height/screenHeight;

//第七步 获取最小比率

int sampleSize = 1;

if(widthSample>heightSample){

sampleSize = heightSample;

}else {

sampleSize = widthSample;

}

//第八步 根据计算出来的比率设置

options.inSampleSize = sampleSize;

//设置为false

options.inJustDecodeBounds = false;

//设置图片显示的格式

options.inPreferredConfig = Bitmap.Config.RGB_565;

//第九步 加载图片

Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.netc,options);

imageView.setImageBitmap(bitmap);

(2) 质量压缩法

//直接定义为方法,方便大家使用

private Bitmap compressImage(Bitmap image) {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中

image.compress(Bitmap.CompressFormat.JPEG, 100, baos);

int options = 100;

//循环判断如果压缩后图片是否大于100kb,大于继续压缩

while (baos.toByteArray().length / 1024 > 100) {

baos.reset();//重置baos即清空baos

options -= 10;//每次都减少10

//这里压缩options%,把压缩后的数据存放到baos中

image.compress(Bitmap.CompressFormat.JPEG, options, baos);

}

//把压缩后的数据baos存放到ByteArrayInputStream中

ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());

//把ByteArrayInputStream数据生成图片

Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);

return bitmap;

}

(3) 图片按比例大小压缩方法(根据路径获取图片并压缩):

//直接定义为方法,方便大家使用

private Bitmap getimage(String srcPath) {

BitmapFactory.Options newOpts = new BitmapFactory.Options();

//开始读入图片,此时把options.inJustDecodeBounds 设回true了

newOpts.inJustDecodeBounds = true;

Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空

newOpts.inJustDecodeBounds = false;

int w = newOpts.outWidth;

int h = newOpts.outHeight;

//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为

float hh = 800f;//这里设置高度为800f

float ww = 480f;//这里设置宽度为480f

//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可

int be = 1;//be=1表示不缩放

if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放

be = (int) (newOpts.outWidth / ww);

} else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放

be = (int) (newOpts.outHeight / hh);

}

if (be <= 0)

be = 1;

newOpts.inSampleSize = be;//设置缩放比例

//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了

bitmap = BitmapFactory.decodeFile(srcPath, newOpts);

return compressImage(bitmap);//压缩好比例大小后再进行质量压缩

}

情况2 : 就是由于多条图片所引起的。 这里就不得不提出一个观点就是三级缓存。

何为三级缓存? 当初我在学习的时候也被这个高大上的名字吓了一跳,后面了解后其实发现很简单。

三级缓存就是,内存缓存,磁盘缓存,网络缓存;是不是吓你一跳呢?

(1) 内存缓存

用的最多的就是LruCache类

(2)磁盘缓存

用的最多的就是DiskLruCache类

(3) 网络缓存

就是连接网络,下载所需要的图片,通常情况下会应用到【情况一】提出的压缩图片。

代码有点多,我到底是贴不贴出来呢?

算了,直接把包上传,需要的就去下载吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: