Drawable和 Bitmap 的区别:
对比项 Bitmap Drawable
显示清晰度 相同 相同
占用内存 大 小
支持缩放 是 是
支持色相色差调整 是 否
支持旋转 是 是
支持透明色 是 是
绘制速度 慢 快
支持像素操作 是 否
引用
http://blog.sina.com.cn/s/blog_5fc933730101ay5x.html
首先 对于第一段代码 调用getResources().getDrawable()获得1000个Drawable()对象 我相信评论中说的是正确的 :
Drawable[] array 中的所有Drawable都指向同一个R.drawable.img的Drawable对象
第三段代码换用BitmapFactory.decodeStream()创建Bitmap对象 在创建第566个Bitmap的时候OOM
文末说用Drawable.createFromStream()创建Drawable 也是在创建第566个Drawable的时候OOM
这正说明了Shelly所说的,Drawable与Bitmap在此种情况下内存占用是完全一致的
根据OOM时的LOG :
04-07 22:16:12.916: E/filemap(8091): mmap(0,416798) failed: Out of memory
在此状态下 平均每个Drawable或Bitmap所占的内存约小于736K (416798/566)
第二段代码 调用BitmapFactory.decodeResource()来创建Bitmap对象 创建了8个Bitmap后即OOM
根据LOG :
04-07 22:06:05.774: D/dalvikvm(7937): GC_EXTERNAL_ALLOC freed 1K, 50% free 2691K/5379K, external 6026K/7525K, paused 31ms
每次加载完毕后 GC的报告中 external都增加 6026K :6026K/7525K ->12052K/14100K -> 18078K/20126K -> 24104K/26152K -> 30130K/32178K -> 36156K/38204K
因此可认为在此状态下 平均每个Bitmap所占的内存应该是6026K
其内存占用是第三段代码结果的8.2倍(6026K/736K)
其与第三段代码的区别仅在于调用的方法不同: decodeResource() 和 decodeStream()
有关此二者的关系 sevensundark在 http://blog.youkuaiyun.com/sevensundark/article/details/7616450 此帖中阐述了
于是翻看源码,得到执行两种方法时的调用次序:
decodeFile(String pathName) ->decodeFile(pathName, null) -> decodeStream(stream, null, opts)
decodeResource(res, id) -> decodeResource(res, id, null) -> decodeResourceStream(res, value, is, null, opts) -> decodeStream(is, pad, opts)
在opts参数中是含有密度信息的
我们都知道在调用res中指定密度的文件夹下的图片时会根据源图片所在的文件夹和当前设备的密度进行缩放
两个Bitmap的内存占用相差8倍 很有可能是他们的缩放系数刚好相差3倍 这样两个Bitmap的像素数量就相差了9倍 体积也就差了9倍
所以我们完全有理由相信在新浪博主OiSoft在调用decodeStream(is)方法的时候 Android系统采用的缺省密度是160或更低(应该为120)
而decodeResource(res, id)中调用的decodeStream(is, pad, opts)中 参数opts所含的屏幕密度是当前设备的密度 而此密度应该会不小于240(应该为300以上了)
于是Android在调用decodeResource方法建立bitmap的时候就将图片放大了 其效率也随之降低了
首先 对于第一段代码 调用getResources().getDrawable()获得1000个Drawable()对象 我相信评论中说的是正确的 :
Drawable[] array 中的所有Drawable都指向同一个R.drawable.img的Drawable对象
第三段代码换用BitmapFactory.decodeStream()创建Bitmap对象 在创建第566个Bitmap的时候OOM
文末说用Drawable.createFromStream()创建Drawable 也是在创建第566个Drawable的时候OOM
这正说明了Shelly所说的,Drawable与Bitmap在此种情况下内存占用是完全一致的
根据OOM时的LOG :
04-07 22:16:12.916: E/filemap(8091): mmap(0,416798) failed: Out of memory
在此状态下 平均每个Drawable或Bitmap所占的内存约小于736K (416798/566)
第二段代码 调用BitmapFactory.decodeResource()来创建Bitmap对象 创建了8个Bitmap后即OOM
根据LOG :
04-07 22:06:05.774: D/dalvikvm(7937): GC_EXTERNAL_ALLOC freed 1K, 50% free 2691K/5379K, external 6026K/7525K, paused 31ms
每次加载完毕后 GC的报告中 external都增加 6026K :6026K/7525K ->12052K/14100K -> 18078K/20126K -> 24104K/26152K -> 30130K/32178K -> 36156K/38204K
因此可认为在此状态下 平均每个Bitmap所占的内存应该是6026K
其内存占用是第三段代码结果的8.2倍(6026K/736K)
其与第三段代码的区别仅在于调用的方法不同: decodeResource() 和 decodeStream()
有关此二者的关系 sevensundark在 http://blog.youkuaiyun.com/sevensundark/article/details/7616450 此帖中阐述了
于是翻看源码,得到执行两种方法时的调用次序:
decodeFile(String pathName) ->decodeFile(pathName, null) -> decodeStream(stream, null, opts)
decodeResource(res, id) -> decodeResource(res, id, null) -> decodeResourceStream(res, value, is, null, opts) -> decodeStream(is, pad, opts)
在opts参数中是含有密度信息的
我们都知道在调用res中指定密度的文件夹下的图片时会根据源图片所在的文件夹和当前设备的密度进行缩放
两个Bitmap的内存占用相差8倍 很有可能是他们的缩放系数刚好相差3倍 这样两个Bitmap的像素数量就相差了9倍 体积也就差了9倍
所以我们完全有理由相信在新浪博主OiSoft在调用decodeStream(is)方法的时候 Android系统采用的缺省密度是160或更低(应该为120)
而decodeResource(res, id)中调用的decodeStream(is, pad, opts)中 参数opts所含的屏幕密度是当前设备的密度 而此密度应该会不小于240(应该为300以上了)
于是Android在调用decodeResource方法建立bitmap的时候就将图片放大了 其效率也随之降低了