Android bitmap介绍

Bitmap内存模型

1.在Android 2.2(API8)之前,当GC工作时,应用的线程会暂停工作,同步的GC会影响性能。而Android2.3之后,GC变成了并发的,意味着Bitmap没有引用的时候其占有的内存会很快被回收。

2.在Android 2.3.3(API10)之前,Bitmap的像素数据存放在Native内存,而Bitmap对象本身则存放在Dalvik Heap中。Native内存中的像素数据并不会以可预测的方式进行同步回收,有可能会导致内存升高甚至OOM。而在Android3.0之后,Bitmap的像素数据也被放在了Dalvik Heap中。

3.0之前需要手动调用Bitmap.recycle()回收,3.0后当没有引用会自动回收。

内存复用

Android3.0之后支持inBitmap内存复用, 避免了内存的回收及申请过程, 显然性能表现更佳

  • 声明可被复用的Bitmap必须设置inMutable为true;
  • Android4.4(API 19)之前只有格式为jpg、png,同等宽高(要求苛刻),inSampleSize为1的Bitmap才可以复用;
  • Android4.4(API 19)之前被复用的Bitmap的inPreferredConfig会覆盖待分配内存的Bitmap设置的inPreferredConfig;
  • Android4.4(API 19)之后被复用的Bitmap的内存必须大于需要申请内存的Bitmap的内存;
  • Android4.4(API 19)之前待加载Bitmap的Options.inSampleSize必须明确指定为1。

Drawable 和 Bitmap区别

Drawable 只是一个抽象概念, 表示"something that can be drawn", 而 Bitmap 是其存在的实体之一, 虽然Bitmap 并不是继承自Drawable, 但是他们通过 BitmapDrawable建立了联系。

对比项 显示清晰度/占用内存/支持缩放/支持色相色差调整/支持旋转/支持透明色/绘制速度/支持像素操作
Bitmap 相同/大/是/是/是/是/慢/是
Drawable 相同/小/是/否/是是/快/否

Bitmap存储了像素信息,所以支持色相色差等像素级调整,相应的占用内存也更大。

Bitmap占有多少内存

getByteCount()方法是在API12加入的,代表存储Bitmap的色素需要的最少内存。API19开始getAllocationByteCount()方法代替了getByteCount()。

占用内存 = width * height * nTargetDensity/inDensity * nTargetDensity/inDensity * 一个像素所占的内存

一个像素占用多大内存?

  • Bitmap.Config用来描述图片的像素是怎么被存储的?
  • ARGB_8888: 每个像素4字节. 共32位,默认设置。
  • Alpha_8: 只保存透明度,共8位,1字节。
  • ARGB_4444: 共16位,2字节。
  • RGB_565:共16位,2字节,只存储RGB值。

参考文档