个人浅谈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) 网络缓存
就是连接网络,下载所需要的图片,通常情况下会应用到【情况一】提出的压缩图片。
代码有点多,我到底是贴不贴出来呢?
算了,直接把包上传,需要的就去下载吧
情况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) 网络缓存
就是连接网络,下载所需要的图片,通常情况下会应用到【情况一】提出的压缩图片。
代码有点多,我到底是贴不贴出来呢?
算了,直接把包上传,需要的就去下载吧
相关文章推荐
- NGUI:UIAtlas
- iOS开发系列--让你的应用“动”起来
- 动画 简单的放大收缩
- java web渲染器
- R连接SQL SERVER
- 结构型模式之一——适配器模式
- NGUI:UIAnchor
- Set-ADUser用法
- java 调用webservice的各种方法总结
- Standard Library Modules Using Notes
- iptables NAT地址池中的地址选取
- flume单channel多sink的测试
- Java UDP
- 利用DirectSound实现声卡录音
- NGUI:UICamera
- NGUI:UIPanel
- 给APP增加RSA签名
- leetcode面试准备: Maximal Rectangle
- C++中创建、初始化以及删除 以变量为大小的动态二维数组
- 第四周项目一建立单链表