Android大图片背景性能优化篇
程序员文章站
2024-03-17 19:47:34
...
内存优化-Android大图片
最近在做一个游戏项目,项目中使用大量的1080P作为背景图片,整个APP内存很快就超过峰值,导致项目中出现多处内存溢出、掉帧现象。
Meizu Mx4pro(260M左右)仅供参考
XiaoMi (260M左右)仅供参考
三星S8(260M左右)仅供参考
调试手机用的是魅族MX4,以一张1280*720大背景图片为样例,我们来计算下一张720P图片占用内存
Android 默认使用的ARGB_8888,也就是32位
一张720P图片占用内存:
1280*720*4/1024/1024=3.515625M
下面我们使用代码测试下内存使用情况:
ImageView iv= (ImageView) findViewById(R.id.test);
BitmapFactory.Options options = new BitmapFactory.Options();
//设置图片比率,1是1/1、2是1/2、3是1/3,设置该参数会影响图片的质量
options.inSampleSize =1;
//ALPHA_8就是Alpha由8位组成
//ARGB_4444就是由4个4位组成即16位,
//ARGB_8888就是由4个8位组成即32位,
//RGB_565就是R为5位,G为6位,B为5位共16位
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap img =BitmapFactory.decodeResource(getResources(),R.drawable.hall_bg,options);
iv.setImageBitmap(img);
Log.d("MainTest",""+img.getRowBytes()*img.getHeight()/(1024*1024));
一张1280*720图片,放在drawable目录下,测试占用内存
目录 | 内存 |
---|---|
drawable | 56.25M |
这和我们前面算出的内存不一致,测试发现放在drawable目录下对应的图片会进行相应拉伸,魅族MX4Pro宽高各拉伸了4倍
drawable目录下内存 4*4*3.5=56.25M 刚好
不同的手机测试内存大小不一致,小米手机宽高拉伸3倍,中兴手机测试宽高拉伸2倍多
于是决定把官方所有的目录测试一遍,对应目录如下
目录 | 占用内存 |
---|---|
drawable | 56.25M |
drawable-anydpi | 3.47M |
drawable-hdpi | 24.99M |
drawable-ldpi | 100M |
drawable-mdpi | 56.25M |
drawable-nodpi | 3.51M |
drawable-xhdpi | 14.06M |
drawable-xxhdpi | 6.25M |
drawable-xxxhdpi | 3.51M |
mipmap | 56.25M |
mipmap-anydpi | 3.47M |
mipmap-hdpi | 24.99M |
mipmap-ldpi | 100M |
mipmap-mdpi | 56.25M |
mipmap-nodpi | 3.51M |
mipmap-xhdpi | 14.06M |
mipmap-xxhdpi | 6.25M |
mipmap-xxxhdpi | 3.51M |
经过上面的测试后得出一个优化方案
资源目录处理:
所有的大背景图片,统一放在mipmap-nodpi目录,用一套1080P素材可以解决大部分手机适配问题,不用每个资源目录下放一套素材
局限性:
宽高要固定,wrap_content属性某些场景下不起作用,目前发现这一个问题
代码处理:
ImageView iv= (ImageView) findViewById(R.id.test);
BitmapFactory.Options options = new BitmapFactory.Options();
//**这个属性很重要,是否支持缩放,false不支持缩放,就是图片按原比例展示**
options.inScaled = false;
//**设置图片比率,1是1/1、2是1/2、3是1/3,设置该参数会影响图片的质量**
options.inSampleSize =1;
//**使用RGB_565可以比系统默认RGB_888内存再减少1倍,会损失部分精度,测试看效果肉眼看不出来差距**
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap img =BitmapFactory.decodeResource(getResources(),R.drawable.hall_bg,options);
iv.setImageBitmap(img); Log.d("MainTest",""+img.getRowBytes()*img.getHeight()/(1024*1024));
代码处理,局限性:
适合单张大图片处理
上一篇: 二分查找上下界
下一篇: 前端性能优化-图片滚动分页懒加载