问题背景
开发的产品跑monkey时在部分机型上会出现oom,最终堆栈信息都是指向BitmapFactory.decodeStream也就是decode图片到内存时出现的。借着这个机会总结一下Bitmap使用过程中需注意的点及优化。
- decode图片时内存占用是怎么计算的?
- BitmapFactory.decodeXXX api会对图片做哪些操作?
- 该如何优化?
问题分析
我们先看看内存占用是怎么计算的
为了了解图片内存占用是怎么计算的,我们先要了解一下安卓支持的颜色模式:
颜色模式 | 备注 | 每个像素存储大小 |
---|---|---|
ARGB_8888 | 四通道高精度(32位) | 4 bytes |
ARGB_4444 | 四通道低精度(16位) | 2 bytes |
RGB_565 | 屏幕默认模式(16位) | 2 bytes |
ALPHA_8 | 仅有透明通道(8位) | 1 bytes |
这些模式在Bitmap.Config下有定义,不多解释各自模式的含义了。我们只需要知道模式位数越高代表其可以存储的颜色信息越多,图像也就越逼真。我们一般使用最多的就是ARGB_8888了。
那我们decode一个图片到内存时计算规则就是图片的像素 width * height * (模式对应的像素大小)
例如一张480*800的ARGB_8888模式的图片,加载到内存中也就是480 * 800 * 4 bytes。(与图片占用空间大小是无关的)
BitmapFactory.decodeXXX api会对图片做哪些操作?
在使用过程中有时候你会发现图片像素是480×800,但是使用decode api 得到的bitmap宽高不是原图片的大小,这是因为使用BitmapFactory的decode api时,会根据BitmapFactory.options参数对图片做缩放处理。让我们看下decodeResourceStream的代码:
/**
* Decode a new Bitmap from an InputStream. This InputStream was obtained from
* resources, which we pass to be able to scale the bitmap accordingly.
*/
public