【腾讯TMQ】静态测试技术之Lint冗余资源清理

来源:互联网 发布:济南js复合保温模板 编辑:程序博客网 时间:2024/06/05 17:16

引言:谈到冗余资源清理,我们不妨先来看看Android的资源组织方式和访问方式。

一、Android资源组织方式及访问方式

新建一个android工程后,默认资源路径res下生成对应的layout、drawable、values等子目录,分别对应以下几类常见的非代码资源:

layout,menu,anim等,代表res资源的顶层使用者,通过xml的方式组合控件,渐变动画等资源,给Activity等组件提供视图,通过这些xml脚本取代代码实现的布局&动效,解耦视图和界面逻辑,提升开发效率;
values,color,xml等,这一类代表res中的文本资源,都是xml格式资源,values主要存放arrays,attrs,colors,dimens,ids,string,integers,theme等基础资源,支持比较丰富的语言扩展;color主要存放返回color资源的selector资源;没有明确归属目录的xml资源,都可以放到xml目录下;
drawable,drawabld-xxx,raw等,这一类代表res中的多媒体资源,有比较丰富分辨率扩展,其中drawable目录主要存放返回drawable格式的selector,带nodpi标签主要存放一些与分辨率无关的9.png资源,其他带xxdpi等目录对应相应的分辨率机型,没有明确归属的非xml资源都可以放到raw目录下。
在资源目录中分类组织资源后,我们就可以通过引用资源 ID 来引用资源,所有资源的ID 都在项目中aapt工具自动生成的./gen/R 类中定义,该文件不能被手动修改,当资源发生变动时,它会相应更新。
访问资源的方法主要有两种:
1、在代码中:R.resource_type.resource_name (引用自定义资源) 或者 android.R.resource_type.resource_name(引用系统标准资源),比如R.string.hello,string 是资源类型,hello 是资源名称,API可以通过这种语法来访问定义的资源,如:getResources().getString(R.string.hello);
2、在 XML 中:使用对应的XML 语法,@[package:]type/name,例如@string/hello,string 是资源类型,hello 是资源名称,可以在 XML 资源通过该语法来访问定义的资源,如:android:text=”@string/hello” 。

二、冗余资源的清理

随着长时间的版本迭代,工程中会冗余许多资源文件,手动查找删除效率太低难免有漏网之鱼,代码扫描工具可以方便的查找出未被引用的图片、ID等资源,本文主要应用Android lint的unUsedResources规则进行冗余资源查找清理。
Android Lint是针对Android的静态代码分析工具,能够对Android项目中潜在的bug、可优化的代码、安全性、性能、可用性、可访问性、国际化等进行检查。
在Android SDKTools 16及更高的版本中,Lint工具会自动安装。通过对Android工程源代码等进行扫描检查,可发现潜在的问题,更好的提升代码质量。
通过lint进行冗余资源清理主要有以下几种方式:
1、我们可以通过lint –check unUsedResources查找冗余资源列表然后手工或者通过其他删除工具加以清理。
2、如果工程使用的是gradle打包,可以在build.gradle中打开shrinkResources开关,这样打包的时候不会把冗余资源打包进来:shrinkResources true // 移除无用的resource文件
3、也可以在Android Studio中使用Analyze-unUsedResources项查找出所有未被引用的资源列表:

在结果上右键选择ApplyFix’Android Lint Quick Fixes’,可以直接删除所有无用的资源:

可能存在的误删除与白名单配置
lint扫描工具无法判断出通过反射方式(android.content.res.Resources#getIdentifier)来获取的资源,可能会产生误删除,如:

此时资源被清理后界面上会找不到图片,如果工程中有该用法可以通过以下几种方式对资源添加白名单配置:
1、局部配置:在XML文件中通过tools:ignore=”UnusedResources”属性配置忽略:
在xml文件开头声明命名空间tools,并为对应的element加上tools:ignore=”UnusedResources “,tools:ignore属性对其xml节点的所有子节点都生效:
我知道了
2、 全局配置:在Android工程的根目录下创建一个名叫lint.xml的文件,如非xml资源可以通过这种方式添加白名单,IDE会读取根目录下的配置,命令行下可以通过—config指定具体配置,需要注意的是,如果工程根目录下存在lint.xml时,–config命令指定的参数无效:

配置文件中支持几个维度的自定义配置:

(1)规则id级别调整,置为ignore则该规则不生效,如:

(2)路径忽略,如:

(3)正则表达式忽略,如:

三、冗余资源清理原理解析

Lint扫描工具是如何扫描出冗余资源的呢,我们先来认识下LintUnusedResources扫描规则,从源码中规则的定义可以看到,UnusedResourceDetector继承自ResourceXmlDetector和Detector.JavaScanner ,查找范围包括Manifest,资源文件,java源文件及测试代码:

1、根据R.java获取资源列表:
Detetor类中JavaScanner接口定义的getApplicableNodeTypes()需要与createJavaVisitor()配合使用,getApplicableNodeTypes()返回我们感兴趣的Node列表,然后在createJavaVisitor()返回的AstVisitor中去处理这些Node。
定义一个AstVisitor的子类,并在createJavaVisitor()中返回它的一个实例,那么当扫描到符合定义语句对应的node就会触发UnusedResourceVisitor()中对应的回调函数:

2、查找代码中的引用:
Detetor类中JavaScanner接口定义的appliesToResourceRefsh()需要与visitResourceReference()函数配合使用,appliesToResourceRefsh()返回true,那么代码中的资源引用会触发visitResourceReference()处理函数:

3、同样的,查找xml文件中的引用:

4、从收集到的资源声明列表中删除被引用的资源列表并去除xml中声明不做处理(如tools:ignore=”UnusedResources”)或配置了白名单的资源,剩余的资源列表可认为是冗余资源:

5、report最终未被引用的资源列表:

四、手管的冗余资源清理应用

清楚了lint冗余资源的清理规则,我们可以放(小)心(心)地开始删删删了,谨慎起见,提供本地工具由开发童鞋本地清理确认,同时在持续集成平台自动监控冗余资源清理情况,形成一键清理+自动监控的灵活处理模式:
1、一键清理:在lint扫描结果的基础上提供命令行清理/还原工具,支持本地一键清理:

(1)清理:

调用lint unUsedResources扫描规则生成冗余资源的xml文件,解析该结果xml文件区分文件格式和xml属性格式的资源(资源格式见本文第一节),批量删除两种不同格式的资源,并在执行路径下生成备份路径按res原路径结构备份删除的内容,支持多次循环调用直至冗余资源结果为0。

(2)还原:

将备份路径下的文件或xml属性资源还原到原路径,并自动添加到lint白名单。

2、自动监控:在持续集成平台上集成清理工具,输出冗余资源清理前后两个安装包及清理资源集,及时监控项目中的冗余资源情况,也可以直观看到清理带来的优化效果,推动项目组在发布前清理冗余资源。
也附上在手管6.8.1版本代码的清理结果:删除文件资源950+个,其他各类型属性2500+个,包大小缩小2.11M,预计在7.0页面改版可以达到更好的应用效果。

冗余资源清理是借助静态代码分析工具的一个小应用,大家在项目过程中是否有其他静态分析工具应用的场景呢?
欢迎大家一起探讨。

参考资源:
[1]https://developer.android.com/guide/topics/resources/index.html;
[2]Android资源管理-drawable篇;
[3]http://tools.android.com/tips/lint/writing-a-lint-check;
[4]https://android.googlesource.com/platform/tools/base/+/master/lint;
[5]微桌面Android资源清理工具。

【TMQ新书专栏】https://weidian.com/?userid=984448577

原文链接:http://tmq.qq.com/2017/02/newapi_lint/

关注我们的微信公众号查看完整内容哦~~~~

想知道更多测试相关干货
请关注我们的微信公众号:腾讯移动品质中心TMQ 。
二维码:
这里写图片描述

版权声明:腾讯TMQ拥有内容的全部版权,任何人或单位对本贴内容进行复制、转载时请申明原创腾讯tmq,否则将追究法律责任。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝商家拒绝退款怎么办还没收货的 拼多多点错确认收货了怎么办 被别人用菜刀砍伤没钱看病怎么办 东京下了订单但不发货怎么办 绑定卷皮钱包的手机号码丢了怎么办 小孩回奶在垫的被子上发霉了怎么办 2个月宝宝不喝母乳只喝奶瓶怎么办 我的扣扣被盗了朋友别被骗了怎么办 我买的股票退市了我的钱怎么办啊 在美食林被门口买宝石的骗了怎么办 在商场买的彪马鞋子皮子裂了怎么办 手机换号了京东钱包里的余额怎么办 寄报销发票给顺丰快递搞丢了怎么办 物流显示揽件但把快递弄丢了怎么办 在李宁商城上买的东西丢了怎么办 我的货发物流都过了好几天怎么办 运动鞋子买小了一码有些挤脚怎么办 媳妇先动手打我我又打媳妇了怎么办 京东商城买个电视没验收破了怎么办 钱充给波克城市游戏还不能玩怎么办 我的魅族账号密保问题忘记了怎么办 在手机店买手机买贵了被骗了怎么办 信翼4g上网宝登录密码忘了怎么办 信翼4g上网宝管理密码忘了怎么办 淘宝上买了货但店铺消失了怎么办啊 微信的版本过低登陆不了微信怎么办 红米3用联通4g卡无信号怎么办 网店跟买家说好有货又没货怎么办 新买的号码被别人注册过微信怎么办 买了个号码卡已经被注册微信怎么办 我怎么办微信把拉黑一次删了人太多 国家大剧院的票丢了能补票吗怎么办 打完狂犬疫苗后我抽了很多烟怎么办 我老婆接受了我的小三现在该怎么办 今日头条我发的文章浏览量少怎么办 如果荷兰猪母的和公的打架该怎么办 我买的商铺地址被别人注册了怎么办 搜狗阅读购买搜豆没有到账该怎么办 捡的ⅴⅰⅴo指纹屏锁解不开怎么办 在百度上订的演出票不配送了怎么办 我在租车公司租的车撞报废了怎么办