1、关于Bitmap
在安卓2.3.3(API级别10)之前,Bitmap像素数据和Bitmap对象是分开存储的,像素数据是存储在native memory中,对象存储在Dalvik heap中,native memory中的像素数据不是以一种可预见的方式释放,可能导致应用程序暂时超过其内存限制和崩溃,所以在Android2.3.3(API 10)之前你必须要调用recycle()方法来释放掉内存避免出现OOM,当然前提是确定这个bitmap不再使用,否则会出现 "Canvas: trying to use a recycled bitmap".
在Android3.0(API 11)之后,Bitmap的像素数据和Bitmap对象一起存储在Dalvik heap中,所以我们不用手动调用recycle()来释放Bitmap对象,内存的释放都交给垃圾回收器来做。
2、资源图片占的内存
我们图片的尺寸是720×1280,所有像素点占用内存=720x1280x4=3686400 byte=3.515625M,这个大小是图片不做任何处理时占用的内存大小。但是系统在将图片处理成Drawable对象的时候会作一些处理。
有两个非常重要的参数,inDensity和inTargetDensity:
1、inDensity表示被设定的图像密度,决定这个值的是图片所放置的文件目录,比如drawable-hdpi、drawable-xhdpi等等,其对应的density如下表:
如果图片放在drawable-hdpi下,inDensity=240
2、inTargetDensity表示最终需要适配到的图片密度,这个值由手机设备来决定,手机屏幕越高清这个值越大,而我们例子中720p的小米2S对应的densityDpi=320。
如果inDensity的值和inTargetDensity的值不相等,那么图片尺寸就被会缩放,缩放的比例为 inTargetDensity / inDensity。
因为图片占用内存与图片的尺寸有关,如果被尺寸缩放了,内存大小就变了。前面未作任何缩放处理的720×1280图占用内存是3.515625M,假设放在drawable-ldpi目录下inDensity=120,设备inTargetDensity=320,那么最终的占用内存大小将是3.515625Mx(320/120)x(320/120)=25M。
一张图片占用25M大小,很恐怖的一个值,这种情况下,app估计直接挂了,如果放在drawable-hdpi下,占用就是6.25M,drawable-xhdpi下占用是3.515625M。由此可见,图片放置的目录一定要慎重。
最终我们得出一个公式:
资源图片内存大小 = 宽 x 高 x 4 x (设备密度 / 资源维度密度)x(设备密度 / 资源维度密度)