Android性能优化学习记录(三)Bitmap 与 资源节省性优化
一、Bitmap优化原因
- 为什么要优化图片
Bitmap
资源?
因为Android系统分配给每个应用程序的内存有限,图片资源(Bitmap)非常消耗内存,很多情况下,图片所占的内存占整个App内存的大部分 - 如果对
Bitmap
的使用或内存管理稍有不当,就可能引发OutOfMemoryError
(内存溢出),容易造成Crash
(应用崩溃)
具体优化方案
主要 从 以下四个方面优化图片Bitmap
资源的使用 & 内存管理
使用完毕后 释放图片资源
优化原因
使用完毕后若不释放图片资源,容易造成内存泄露,从而导致内存溢出
优化方案
a. 在 Android2.3.3(API 10)前,调用 Bitmap.recycle()方法
b. 在 Android2.3.3(API 10)后,采用软引用(SoftReference)
具体描述
在 Android2.3.3(API 10)前、后,Bitmap对象 & 其像素数据 的存储位置不同,从而导致释放图片资源的方式不同,具体如下图
版本号 | 存储方式(Bitmap对象与像素数据) | 内部的内存资源释放机制 | 优化内存资源释放方式 |
---|---|---|---|
Android2.3.3(API 10)前 | 分开存储 |
- Bitmap对象:存储在堆内存中
- Bitmap对象的像素数据:存储在本地内存(Bitmap实例通过JNI调用方式生成,使其像素数据存储在本地内存) | 1. Bitmap对象:GC(Java垃圾回收器)
- Bitmap对象的像素数据:不可预知的方式释放(GC无法直接回收在本地内存中的资源) | 1. Bitmap对象:由(GC)Java垃圾回收器 自动回收+软引用(SoftReference)(软引用(SoftReference):若内存空间不足时,才回收这些对象的内存)
- Bitmap对象的像素数据:调用Bitmap.recycle()
(recycle()源码中调用了JNI方法释放该部分资源) |
| Android2.3.3(API 10)后 | 共同存储 | GC(Java垃圾回收器) | 均由(GC)Java垃圾回收器自动回收+SoftReference(软引用)) |
注:若调用了Bitmap.recycle()后
,再绘制Bitmap
,则会出现Canvas: trying to use a recycled bitmap
错误
根据分辨率适配 & 缩放图片
- 优化原因若
Bitmap
与 当前设备的分辨率不匹配,则会拉伸Bitmap
,而Bitmap
分辨率增加后,所占用的内存也会相应增加
因为Bitmap
的内存占用 根据 x
、y
的大小来增加的
- 优化方案
优化方式 | 具体描述 | 备注 |
---|---|---|
设置多套图片资源 | 将图片放到 hdpi/xhdpi/xxhdpi等不同文件夹进行适配 | |
BitmapFactory.decodeResource() | 1. 对Bitmap根据当前设备屏幕的像素密度值进行缩放适配 | |
BitmapFactory.inSampleSize | 缩放图片比例,使得图片按分辨率加载,避免不必要大图加载 | 1. 此参数为int值,若<1时会被当做1处理,若>1,则按照1/inSampleSize比例缩小bitmap的宽和高、降低分辨率 |
示例:如果width=100,height=100,inSampleSize=2,则处理后width=50,height=50,宽高降为1/2,像素数降为1/4 |
按需 选择合适的解码方式
- 优化原因
不同的图片解码方式 对应的 内存占用大小 相差很大,具体如下
储备知识:ARGB
ARGB:一种色彩模式,A是Alpha透明度,R是red红色,G是green绿色,B是blue蓝色。
作用是用来描述与存储色彩颜色的信息(注:所有可见色都由红绿蓝组成,所以红绿蓝称为三原色,每个原色都存储着所表示颜色的信息值)
Bitmap存在四种解码方式(属性)
属性(public static final Bitmap.Config) | 含义 | 色彩组成 | 内存组成 | 1个像素点占用内存 |
---|---|---|---|---|
ARGB_4444 | 16位ARGB位图 | 颜色+透明度 | 4个4位组成(16位) | |
每个像素占4位,A=4、R=4、G=4、B=4 | 4+4+4+4=16位、2字节 | |||
ARGB_8888 | 32位ARGB位图 | 颜色+透明度 | 4个8位组成(32位) | |
每个像素占8位,A=8、R=8、G=8、B=8 | 8+8+8+8=32位=4字节 | |||
RGB_565 | 16位RGB位图 | 颜色(无透明度) | 每个像素分别占R=5、G=6、B=5 | 5+6+5=16位=2字节 |
ALPHA_8 | 8位Alpha位图 | 透明度(无颜色) | 仅由8位透明度组成,每个像素A=8位 | 8位=1字节 |
- 位图位数越高,代表其可存储的颜色信息越多,图像越逼真
- 一般情况下,使用ARGB_8888最占内存 1个像素占4字节
- 若有一张480*800的图,格式为ARGB_8888则占1500KB内存
- 优化方案
根据需求选择合适的解码方式
- 使用参数
BitmapFactory.inPreferredConfig
设置。2. 默认使用解码方式:ARGB_8888
设置 图片缓存
- 优化原因
重复加载图片资源耗费太多资源(CPU
、内存 & 流量) - 优化方案
优化方式 | 具体描述 |
---|---|
三级缓存机制 | 内存缓存-本地缓存-网络缓存 |
当加载Bitmap图片资源时,先从内存缓存中寻找 | |
若内存缓存中没有,则从本地缓存中寻找 | |
本地缓存中没有,则从网络中加载获取 | |
软引用(SoftReference) | 使用SoftReference(软引用)实现内存敏感的高速缓存 |
(SoftReference(软引用):内存空间不足时,才回收这些对象的内存) |
总结
二、资源节省性
由于移动设备的硬件性能有限,故减少应用程序的资源消耗显得十分重要。
- 优化方向:内存大小、安装包大小、耗电量 & 网络流量
内存优化
- 优化原因:避免因不正确使用内存 & 缺乏管理,从而出现 内存泄露
(ML)
、内存溢出(OOM)
、内存空间占用过大 等问题,最终导致应用程序崩溃(Crash
) - 优化方向常见的内存问题如下
- 内存泄露
- 内存抖动
- 图片
Bitmap
相关 - 代码质量 & 数量
- 日常不正确使用
- 具体优化方案:内存泄漏解决、内存优化
减少安装包大小
- 优化原因:应用程序的安装包大小虽对应用程序的使用无影响,但影响的是:
- 空间占有率:即 应用程序占有手机内存的大小
- 下载门槛:应用的安装包越大,用户下载的门槛越高
减少网络流量
- 优化原因:每次获取资源时 都通过流量 & 网络加载的方式,将耗费大量网络流量
- 优化方案主要通过 缓存 减少网络流量,采用三级缓存方案:即 内存缓存 - 硬盘缓存- 数据库- 文件(本地缓存) - 网络缓存
减少应用的耗电量
- 优化原因
随着智能手机普及 & 应用程序App
的功能发展,人们的日常生活都离不开智能手机 & 各式各样的应用程序App
,故 应用程序的耗电量指标则显得十分重要
总结
参考资料
https://carsonho.blog.csdn.net/article/details/79708444