(1)每个进程分配的内存空间是多少?
我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状、不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小。比如说系统图片库里展示的图片大都是用手机摄像头拍出来的,这些图片的分辨率会比我们手机屏幕的分辨率高得多。大家应该知道,我们编写的应用程序都是有一定内存限制的,程序占用了过高的内存就容易出现OOM(OutOfMemory)异常。我们可以通过下面的代码看出每个应用程序最高可用内存是多少
、当前进程已申请的内存是多少
、在已申请的内存中还有多少剩余的空间
。
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024 / 1024);
Log.d("aaa", "当前进程被分配的最大内存:" + maxMemory + "M");
int freeMemory = (int) (Runtime.getRuntime().freeMemory() / 1024 / 1024);
Log.d("aaa", "当前进程空闲的内存:" + freeMemory + "M");
int totalMemory = (int) (Runtime.getRuntime().totalMemory() / 1024 / 1024);
Log.d("aaa", "当前进程内存总量:" + totalMemory + "M");
有关进程中内存分配的知识,下面的博客写的还可以:
浅谈 maxMemory , totalMemory , freeMemory 和 OOM 与 native Heap
(2)图片压缩
图片压缩分为两种:分辨率压缩
和质量压缩
我们准备三张图片,文件名分别是pic0、pic1、pic2。
pic0:
原图,图片大小为1.05Mpic1:
质量缩减到50%,图片最终大小为255Kpic2:
分辨率缩减到50%,图片最终大小为317K
我们分别通过以下代码求出它们所占Bitmap的大小:
Bitmap bitmap0 = BitmapFactory.decodeFile(FileDirUtil.getInstance().getExternalStorageDirectory() + File.separator + "pic0.jpg");
if(bitmap0 != null){
Log.d("aaa", String.valueOf(getBitmapSize(bitmap0) * 1.0f / 1024 / 1024));
}else{
Log.d("aaa", "pic0----bitmap is null");
}
Bitmap bitmap1 = BitmapFactory.decodeFile(FileDirUtil.getInstance().getExternalStorageDirectory() + File.separator + "pic1.jpg");
if(bitmap1 != null){
Log.d("aaa", String.valueOf(getBitmapSize(bitmap1) * 1.0f / 1024 / 1024));
}else{
Log.d("aaa", "pic0----bitmap is null");
}
Bitmap bitmap2 = BitmapFactory.decodeFile(FileDirUtil.getInstance().getExternalStorageDirectory() + File.separator + "pic2.jpg");
if(bitmap2 != null){
Log.d("aaa", String.valueOf(getBitmapSize(bitmap2) * 1.0f / 1024 / 1024));
}else{
Log.d("aaa", "pic0----bitmap is null");
}
/**
* 得到bitmap的大小
*/
private int getBitmapSize(Bitmap bitmap) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //API 19
return bitmap.getAllocationByteCount();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {//API 12
return bitmap.getByteCount();
}
// 在低版本中用一行的字节x高度
return bitmap.getRowBytes() * bitmap.getHeight(); //earlier version
}
pic0求出的bitmap大小为:
6.591797Mpic1求出的bitmap大小为:
6.591797Mpic2求出的bitmap大小为:
1.6479492M
我们发现,pic0求出的bitmap大小和pic1求出的bitmap大小完全一致,于是得出结论:图片质量变化不会影响bitmap的大小,分辨率的变化会影响bitmap的大小
。
当我们加载图像想要防止OOM的话,必须限制bitmap的大小,所以我们需要使用BitmapFactory.Options
来配置解码器的参数。