Bitmap作为位图,需要读入一张图片每一个像素点的数据,其主要占用内存的地方也正是这些像素数据。对于像素数据总大小,我们可以猜想为:像素总数量 × 每个像素的字节大小,而像素总数量在矩形屏幕表现下,应该是:横向像素数量 × 纵向像素数量,结合得到:
Bitmap内存占用 ≈ 像素数据总大小 = 横向像素数量 × 纵向像素数量 × 每个像素的字节大小
单个像素的字节大小
单个像素的字节大小由Bitmap的一个可配置的参数Config来决定。
Bitmap中,存在一个枚举类Config,定义了Android中支持的Bitmap配置:
| Config | 占用字节大小(byte) | 说明 |
| — | — | — |
| ALPHA_8 (1) | 1 | 单透明通道 |
| RGB_565 (3) | 2 | 简易RGB色调 |
| ARGB_4444 (4) | 4 | 已废弃 |
| ARGB_8888 (5) | 4 | 24位真彩色 |
| RGBA_F16 (6) | 8 | Android 8.0 新增(更丰富的色彩表现HDR) |
| HARDWARE (7) | Special | Android 8.0 新增 (Bitmap直接存储在graphic memory)注1 |
**注1:**关于Android 8.0中新增的这个配置,stackoverflow已经有相关问题,可以关注下。
之前我们分析到,Bitmap的decode实际上是在native层完成的,因此在native层也存在对应的Config枚举类。
一般使用时,我们并未关注这个配置,在BitmapFactory中,有:
- Image are loaded with the {@link Bitmap.Config#ARGB_8888} config by default.
*/
public Bitmap.Config inPreferredConfig = Bitmap.Config.ARGB_8888;
因此,Android系统中,默认Bitmap加载图片,使用24位真彩色模式。
Bitmap占用内存大小实例
首先准备了一张800×600分辨率的jpg图片,大小约135k,放置于res/drawable文件夹下:
并将其加载到一个200dp×300dp大小的ImageView中,使用BitmapFactory。
Bitmap bitmapDecode = BitmapFactory.decodeResource(getResources(), resId);
imageView.setImageBitmap(bitmapDecode);
打印出相关信息:
图中显示了从资源文件中decode得到的bitmap的长、宽和占用内存大小(byte)等信息。
首先,从数据上可以验证:
17280000 = 2400 * 1800 * 4
这意味着,为了将单张800 * 600 的图片加载到内存当中,付出了近17.28M的代价,即使现在手机运存普遍上涨,这样的开销也是无法接受的,因此,对于Bitmap的使用,是需要非常小心的。好在,目前主流的图像加载库(Glide、Fresco等)基本上都不在需要开发者去关心Bitma