使用python 和 lint 删除项目无用资源的方法


Posted in Python onDecember 20, 2017

有部分老项目是在Eclipse环境开发的,最近公司要求应用瘦身,老项目也在其中。如果在 AS 下开发就不会有这样的问题,但是在 Eclipse 中就不太方便了,于是就写了这个脚本。第一次用Python写东西,代码里可能会有许多 Java、C 这样的痕迹,见谅。

使用方法

将 python 目录下的 delUnused.py 放到项目目录下,然后直接运行即可。

代码说明

利用lint进行代码审查

lint --check UnusedResources --xml [resultPath] [projectPath]

命令含义是检查项目中未使用的资源文件,并且用xml格式输出结果,需要提供检查结果输出的路径和项目路径。在脚本中已经自动提供了。

def exec_lint_command():
 cmd = 'lint --check UnusedResources --xml %s %s' % (_get_lint_result_path(), _get_project_dir_path())
 p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
 c = p.stdout.readline().decode()
 while c:
  print(c)
  c = p.stdout.readline().decode()

这里给一个检查结果实例吧

<issue
  id="UnusedResources"
  severity="Warning"
  message="The resource `R.layout.activity_all_player` appears to be unused"
  category="Performance"
  priority="3"
  summary="Unused resources"
  explanation="Unused resources make applications larger and slow down builds."
  errorLine1="<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
"
  errorLine2="^"
  quickfix="studio">
  <location
   file="res\layout\activity_all_player.xml"
   line="2"
   column="1"/>
 </issue>

我们能用到的信息有 id message location 等。

解析检查结果

我是利用 minidom 解析的,具体的解析方法不多说,参考。

获取根节点

def _parse_lint_report():
 file = minidom.parse(_get_lint_result_path())
 root = file.documentElement
 beans = _parse_xml(root)
 return beans

解析第一层子节点

def _parse_xml(element, beans=None):
 if beans is None:
  beans = []
 for node in element.childNodes:
  if node.nodeName == ISSUE_KEY and node.nodeType is node.ELEMENT_NODE:
   lint_bean = _LintBean()
   lint_bean.id = node.getAttribute(ID_KEY)
   lint_bean.severity = node.getAttribute(SEVERITY_KEY)
   lint_bean.message = node.getAttribute(MESSAGE_KEY)
   _parse_location(node, lint_bean)
   lint_bean.print()
   beans.append(lint_bean)
 return beans

解析location 子节点

def _parse_location(node, bean):
 if not node.hasChildNodes():
  return
 for child in node.childNodes:
  if child.nodeName == LOCATION_KEY and node.nodeType is node.ELEMENT_NODE:
   bean.location.file = child.getAttribute(LOCATION_FILE_KEY)
   bean.location.line = child.getAttribute(LOCATION_LINE_KEY)
   bean.location.column = child.getAttribute(LOCATION_COLUMN_KEY)

用Java习惯了,解析数据喜欢用Bean

class _Location(object):
 def __init__(self):
  self.file = ''
  self.line = 0
  self.column = 0

class _LintBean(object):
 def __init__(self):
  self.id = ''
  self.severity = ''
  self.message = ''
  self.location = _Location()

 def print(self):
  print('find a %s, cause: %s. filePath: %s. line: %s' % (
   self.id, self.message, self.location.file, self.location.line))

处理无用资源

解析完数据,可以得到三种资源:

  • Drawable,就一个文件,可以直接删
  • xml中的一个节点,但是这个xml中就这一个节点,直接删文件
  • xml中的一个节点,这个xml中有多个节点,删除节点

对这三种资源进行区分和删除

for lint in lint_result:
 total_unused_resource += 1
 if lint.id != 'UnusedResources':
  continue
 if lint.location.line != '':
  is_single = _is_single_node(lint.location.file)
  if is_single:
   total_del_file += 1
   del_file(lint.location.file)
  else:
   total_remove_attr += 1
   node_name = get_node_name(lint.message)
   del_node(lint.location.file, node_name)
 else:
  total_del_file += 1
  del_file(lint.location.file)

删除文件

def del_file(file_path):
 try:
  os.remove(file_path)
  print('remove %s success.' % file_path)
 except FileNotFoundError:
  print('remove %s error.' % file_path)

删除节点:

def del_node(file_path, node_name):
 file = minidom.parse(file_path)
 root = file.documentElement
 nodes = root.childNodes
 for node in nodes:
  if node.nodeType in (node.TEXT_NODE, node.COMMENT_NODE):
   continue
  if node_name == node.getAttribute('name'):
   root.removeChild(node)
   file.writexml(open(file_path, 'w', encoding='UTF-8'), encoding='UTF-8')
   print('remove %s, node_name:%s. success!' % (file_path, node_name))
   return

总结

以上所述是小编给大家介绍的使用python 和 lint 删除项目无用资源的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
python中如何使用朴素贝叶斯算法
Apr 06 Python
python实现12306火车票查询器
Apr 20 Python
Mac中Python 3环境下安装scrapy的方法教程
Oct 26 Python
python语言中with as的用法使用详解
Feb 23 Python
Python实现的爬取网易动态评论操作示例
Jun 06 Python
用pyqt5 给按钮设置图标和css样式的方法
Jun 24 Python
Django forms表单 select下拉框的传值实例
Jul 19 Python
Python:slice与indices的用法
Nov 25 Python
python 计算方位角实例(根据两点的坐标计算)
Jan 17 Python
如何理解python对象
Jun 21 Python
如何让python的运行速度得到提升
Jul 08 Python
python 经纬度求两点距离、三点面积操作
Jun 03 Python
python机器学习实战之K均值聚类
Dec 20 #Python
Python绘制3d螺旋曲线图实例代码
Dec 20 #Python
python机器学习实战之最近邻kNN分类器
Dec 20 #Python
python3.6 +tkinter GUI编程 实现界面化的文本处理工具(推荐)
Dec 20 #Python
浅谈Python实现Apriori算法介绍
Dec 20 #Python
利用Python如何生成hash值示例详解
Dec 20 #Python
python 3.6 tkinter+urllib+json实现火车车次信息查询功能
Dec 20 #Python
You might like
遍历指定目录下的所有目录和文件的php代码
2011/11/27 PHP
PHP中的事务使用实例
2015/05/26 PHP
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
jQuery DOM操作小结与实例
2010/01/07 Javascript
小议Javascript中的this指针
2010/03/18 Javascript
使用jquery hover事件实现表格的隔行换色功能示例
2013/09/03 Javascript
Iframe实现跨浏览器自适应高度解决方法
2014/09/02 Javascript
用JavaScript判断CSS浏览器类型前缀的两种方法
2015/10/08 Javascript
详解js中class的多种函数封装方法
2016/01/03 Javascript
bootstrap实现弹窗和拖动效果
2016/01/03 Javascript
详解AngularJS中的http拦截
2016/02/09 Javascript
1秒50万字!js实现关键词匹配
2016/08/01 Javascript
layui导航栏实现代码
2017/05/19 Javascript
微信小程序开发之IOS和Android兼容的问题
2017/09/26 Javascript
ES6 Object属性新的写法实例小结
2019/06/25 Javascript
python matplotlib绘图,修改坐标轴刻度为文字的实例
2018/05/25 Python
python如何求解两数的最大公约数
2018/09/27 Python
对pytorch网络层结构的数组化详解
2018/12/08 Python
python使用flask与js进行前后台交互的例子
2019/07/19 Python
Python 利用flask搭建一个共享服务器的步骤
2020/12/05 Python
澳大利亚最好的在线时尚精品店:Princess Polly
2018/01/03 全球购物
简历中自我评价范文3则
2013/12/14 职场文书
业务员岗位职责范本
2013/12/15 职场文书
2014年公司植树节活动方案
2014/03/04 职场文书
办公设备采购方案
2014/03/16 职场文书
小学模范班主任事迹材料
2014/05/13 职场文书
档案保密承诺书
2014/06/03 职场文书
2015年财务经理工作总结
2015/05/13 职场文书
小学运动会前导词
2015/07/20 职场文书
优秀员工演讲稿
2019/06/21 职场文书
2019送给家人们的中秋节祝福语
2019/08/15 职场文书
关于考试抄袭的检讨书
2019/11/02 职场文书
golang gopm get -g -v 无法获取第三方库的解决方案
2021/05/05 Golang
解析CSS 提取图片主题色功能(小技巧)
2021/05/12 HTML / CSS
MySQL数据库中varchar类型的数字比较大小的方法
2021/11/17 MySQL
Java 多线程并发FutureTask
2022/06/28 Java/Android