1、Android系统中对drawable文件夹的处理
我们开发Android app的时候都会用到drawable文件夹,使用drawable文件夹来放置我们需要的ui图片。
有经验的开发都知道什么大小的图片应该放置到哪个drawable文件夹中,具体文件夹规则如下
DPI主流分辨率目录密度
0dpi ~ 120dpi240x320 240x400drawable-ldpildpi
120dpi ~ 160dpi480x800(or854)(5寸)drawable-mdpi or drawablemdpi
160dpi ~ 240dpi480x800(or854)(4寸or3.7寸)drawable-hdpihdpi
240dpi ~ 320dpi720x1280drawable-xhdpixhdpi
320dpi ~ 480dpi1080x1920drawable-xxhdpixxhdpi
480dpi ~ 640dpi1440x2560drawable-xxxhdpixxxhdpi
以上的分辨率和dpi对应关系并不是固定的,具体还是要自己根据手机屏幕的大小来计算出对应的dpi,算法例子如下
也有少数手机厂商可能会自定义dpi,导致不一致的情况,但这种情况一般不予考虑
如果放错图片位置会发生什么问题呢?如何发生的?
比如我有一张586x387大小的名叫printlogo的png图片放在了hdpi目录下面,使用布局如下
android:src="@drawable/printlogo"
android:layout_width="60dp"
android:layout_height="60dp" />
android:src="@drawable/printlogo"
android:layout_width="160dp"
android:layout_height="100dp" />
android:src="@drawable/printlogo"
android:layout_width="250dp"
android:layout_height="150dp" />
复制代码
然后用720x1280的手机展示这个布局,那这三个ImageView的实际像素大小为120x120 320x200 500x300
而printlogo图片在手机内存中的大小一直都是320/240倍数的大小,即781x516像素大小,这样就会导致多分配了内存
那我们如何检查我们的bitmap分配太多内存?
1、通过一一查看drawable中的图片大小来预估这个图片是否保存在正确的drawable位置
2、通过Android monitor查看bitmap内存使用情况
以上两种方法都费时费力,于是就有了做BitmapCanary可视化检查工具想法
2、BitmapCanary的原理
主要的原理就是在app运行的时候,实时检查View中的BitmapDrawable,判断bitmap大小和view图片的大小是否匹配
Bitmap bitmap = ((BitmapDrawable) backGroupDrawable).getBitmap();
if(bitmap.getHeight()>view.getHeight()*MAX_SCALE
||bitmap.getWidth()>view.getWidth()*MAX_SCALE){
markScaleView(bitmap,view);
}
复制代码
最核心的代码就是这样的,但为了开发者便于使用添加了布局遍历和可视化视图添加
3、BitmapCanary的使用
进入https://github.com/smallnew/BitmapCanary 下载代码
并依赖androidbitmapcanary
ActivityDrawableWatcher.watchDrawable(this);//这样就ok啦复制代码
效果如下:
app界面会有蒙层来表示该图片的位图已经超过了视图的1.5倍(长宽)大小,并有白色数字标明倍数
https://github.com/smallnew/BitmapCanary
总结:
加载图片的时候最好使用glide之类的加载工具,这些工具会帮你减少内存使用,drawable的位置要提前放对。
如果工程里已经有许多错误的drawable位置,那最好使用BitmapCanary来检查