一个很困扰的问题,实际开发过程两个,但是这两个究竟有什么区别呢?看过源码就知道Drawable是一个抽象类,继承它的子类有很多,我使用过的有BitmapDrawable,ColorDrawable,GradienDrawable. Android 5.0推出了一个新的VectorDrawable,矢量图 用来做屏幕适配,以前针对不同的屏幕的分辨率要放不同的大小的图片,有了矢量图后一张图就可以自动适配了。所以就图片这一块来说应该是BitmapDrawable 和Bitmap的区别。
BitmapDrawable继承Drawable,在它的onDraw()方法里可以看到任何一个BitmapDrawable都是基于一个Bitmap对象调用底层方法画出来的
Bitmap是一个final类,位图对象,可序列化对象,实现了Parcelable接口,这也很好理解毕竟Bitmap对象大多在内存里使用,在内存里面的使用Android为移动端推出的Parcelable,性能更好,不像Serializable碎片化严重,会引起频繁的GC
使用场景的不同:Drawable对象一般用来做背景图,父类View通过的设置背景的方法都是Drawable做为参数。而在ImageView里面却可以通过setImageBitmap,直接用Bitmap对象做前景色。如果要用Bitmap做背景色,那就必须要要把bitmap转成Drawable
Drawable drawable = new BitmapDrawable(getResource(),bitmap)
旧的方法Drawable drawable = new BitmapDrawable(bitmap),据说被抛弃的原因是用这种方法没有加getResource()转换过程中有时会没办法正确渲染,为什么设置背景一定要用Drawable,这就可以引出另一个不同了,BitmapDrawable所占内存应该比bitmap小,毕竟bitmap是位图,基于bitmap产生BitmapDrawable在调用底层代码的过程中,google肯定是做了某些优化的.这也就带出了另一个不同绘制速度BitmapDrawable要比Bitmap快,因为两者最后都是调用底层代码实现,无法找到具体的证据,但个人猜想bitmap的绘制其实是0---1的过程,而BitmapDrawable是从那个1---N的过程,显然从无到有会比较难比较慢一点,这个纯属个人猜测.
PS:在设置背景这一简单问题上我可是栽过跟头的,因为我们的compileSdkVersion是21所以我曾经直接调用setBackground(Drawable drawable) API16,可想而知编译没问题,但是运行到4.0的手机上就直接crash了
回收问题:其实不管是Bitmap还是BitmapDrawable都是可以回收的,当它们与某个控件绑定的时候,当控件被回收了它们自然会随控件的销毁而被回收到,只有当两者孤立的存在时,Bitmap调用recycle(),BitmapDrawable调用getBitmap().recycle()进行手动回收