使用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中的多线程实例教程
Aug 27 Python
在Python中使用NLTK库实现对词干的提取的教程
Apr 08 Python
python写入中英文字符串到文件的方法
May 06 Python
Python编程中的文件操作攻略
Oct 16 Python
Django使用redis缓存服务器的实现代码示例
Apr 28 Python
Python OpenCV实现鼠标画框效果
Aug 19 Python
Flask框架学习笔记之路由和反向路由详解【图文与实例】
Aug 12 Python
Python学习笔记之集合的概念和简单使用示例
Aug 22 Python
python多进程并行代码实例
Sep 30 Python
Python中的延迟绑定原理详解
Oct 11 Python
如何在Python中创建二叉树
Mar 30 Python
python process模块的使用简介
May 14 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 设置MySQL连接字符集的方法
2011/01/02 PHP
linux下为php添加curl扩展的方法
2011/07/29 PHP
PHP验证码生成原理和实现
2016/01/24 PHP
jQuery Ajax 全解析
2009/02/08 Javascript
js文件中调用js的实现方法小结
2009/10/23 Javascript
javascript:;与javascript:void(0)使用介绍
2013/06/05 Javascript
javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
2014/05/08 Javascript
jquery制作 随机弹跳的小球特效
2015/02/01 Javascript
clipboard.js无需Flash无需依赖任何JS库实现文本复制与剪切
2015/10/10 Javascript
javascript编程异常处理实例小结
2015/11/30 Javascript
jQuery实现的倒计时效果实例小结
2016/04/16 Javascript
node.js实现回调的方法示例
2017/03/01 Javascript
react native仿微信PopupWindow效果的实例代码
2017/08/07 Javascript
webpack4 处理CSS的方法示例
2018/09/03 Javascript
详解async/await 异步应用的常用场景
2019/05/13 Javascript
微信小程序下拉菜单效果的实例代码
2019/05/14 Javascript
vue集成chart.js的实现方法
2019/08/20 Javascript
React+Redux实现简单的待办事项列表ToDoList
2019/09/29 Javascript
python实现文件路径和url相互转换的方法
2015/07/06 Python
python实现两个文件合并功能
2018/04/01 Python
学习python可以干什么
2019/02/26 Python
python简单实现AES加密和解密
2019/03/28 Python
Python 解决OPEN读文件报错 ,路径以及r的问题
2019/12/19 Python
Pytorch之parameters的使用
2019/12/31 Python
美国最佳选择产品网站:Best Choice Products
2019/05/27 全球购物
生物医学工程专业学生求职信范文分享
2013/12/14 职场文书
外语系毕业生自荐信范文
2013/12/16 职场文书
自我鉴定四大框架
2014/01/17 职场文书
人力资源经理的岗位职责
2014/03/02 职场文书
户外活动策划方案
2014/03/12 职场文书
行政部岗位职责范本
2014/03/13 职场文书
《数星星的孩子》教学反思
2014/04/11 职场文书
三问三解心得体会
2014/09/05 职场文书
2015年党员自评材料
2014/12/17 职场文书
幼儿园圣诞节活动总结
2015/05/06 职场文书
考试后的感想
2015/08/07 职场文书