如何有效的清除Android中无用的资源(静态代码分析)

最近公司要做这个,简单调研了一下,现有的大多数博客也比较旧了,不太合适,总结了这么几个方式吧,一起来学习下。

为什么要清除Android中这些资源呢

是这样的,今天收到的邮件里,有这么一条任务:

资源优化

  软件中无用的图片和布局文件,找到并验证是否无用.       这个需要设计一套工具进行分析(自行设计最好或者第三方)

嗯,好吧...说笑了! 下面是正题↓↓↓↓

其实随着项目不断更新,需求不断变动,一改再改,UI一调再调,结果就是项目中一堆已经用不到但却没有清理的垃圾资源,不说工程大小问题,对新进入项目的人或看其他模块的代码的人来说,这些没清理的资源可能也可能会带来困扰,所以最好还是清理掉这些垃圾,对于一个稍微大一点的工程来说,手工清理明显是不现实的,这就需要一个方法做这些事情。

知识整合

看了很久,总结了一下,我能找到的市面上大概有8种方法来做这件事,觉得里面比较好用的整理一下分为5点,时间原因肯定不能全试啦,因为选出最合适的方法就要开始写成公司自己专门的工具了,简单说一下:

1.看到的第一个方法就是用SDK提供的代码检查工具Android lint

Android lint 删除无用图片文件和配置文件

  • Android lint 在 Android sdk tools 当中 配好环境变量(知道了Lint,这个工具非常强大!强烈推荐研究一下)
  • 输入:lint --check "UnusedResources" /Users/baozi/Dev/android/android > result.txt(可以把无用资源信息输出到result文件)
  • 打开result文件查看信息,会发现在哪一行,叫什么,都会给出相应的评价。
  • 删除:代码如下(非常重要)!借用文中的一句话就是:手工逐条删除 并不符合程序猿三大优秀品质 : 懒惰 没有耐心 骄傲
/**  * 删除 未使用的冗余资源(图片 xml布局)  *   * @param b  *   *            false 显示资源列表  *   *            true 显示资源列表 并删除资源  *   * @throws Exception  */  private static void init(boolean b) throws Exception {      String encoding = "UTF-8"; // 字符格式      String projectPath = "/Users/baozi/Dev/shihui/android/";//Android工程所在地址      String filePath1 = "/Users/baozi";//result的所在路径      File file = new File(filePath1, "result.txt");//获取result.txt 文件 生成地址      if (file.isFile() && file.exists()) { // 判断文件是否存在          InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式          BufferedReader bufferedReader = new BufferedReader(read);          String line = null;          while ((line = bufferedReader.readLine()) != null) {              if (line.contains("UnusedResources") && !line.contains("res/value") && !line.contains("appcompat")                      && !line.contains("res/xml")) {                  // System.out.println(line);                  int end = line.indexOf(":");                  if (end != -1) {                      String file_end = line.substring(0, end);                      String f = projectPath + file_end;                      System.out.println(f);                      if (b) {                          new File(f).delete();                          System.out.println("删除成功");                      }                  }              }          }          read.close();      }  }
  • projectPath : Android工程在硬盘中的位置
  • filePath1 : lint 运行结果 result.txt 所在的位置

方法 参数 传入false 仅打印结果 传入true 打印结果 并删除文件

填入正确的地址 就能批量执行删除未使用的 布局 & 图片 资源 (UnusedResources)

如果想要删除其它操作 请修改 筛选条件
if (line.contains("UnusedResources") && !line.contains("res/value") && !line.contains("appcompat") && !line.contains("res/xml")

使用心得: 循环使用3-6次 能完成 删除全部未使用的资源 但是有些废弃的模块 存在代码以来关系 需要手工判断删除 缺点:判断不准确


2.一个自动清理Android项目无用资源的工具类及源码

原文点此处

优点:把上个方法中找出的无用资源的信息,再删除,整个步骤封装成了一个程序,并且对原GITHUB项目进行了优化:对用到的如string、style等资源进行了处理。 步骤代码较长,就不贴了,详细看原文。


3.Android Studio利用Gradle删除没有使用到的资源和代码文件

原文点此处

利用Gradle来优雅的去除没有用到的资源文件:

android {        buildTypes {            release {                minifyEnabled true                shrinkResources true            }        }    }

缺点:很多没有用到的类还是会被打包进去。去除无效代码的功能要依赖于混淆,混淆又是一个耗时的操作,还是没有彻底解决打包慢的问题。

当然也可以做一些忽略无用的代码优化,所以感觉还不错。


4.利用python自动清除Android工程中的多余资源

原文点此处

该文是博主直接在公司使用的方法,如下:

##################################################环境: win + python 2.7#作者:马波#邮箱:mabo02@baidu.com#部门:hao123-无线#说明:首次使用时lint分析会耗几分钟,请耐心等待。#      使用前先clean工程,确保工程bin下重新生成dex,#      以便lint进行分析。如果要lint重新分析多余#      资源,需要删掉(2)txt记录文件,(1)(3)(4)需要#      根据我们的实际工程手动设置。#      如果清除资源后,工程缺少文件而报错(极少#      情况),尝试通过svn恢复该文件即可。#################################################import subprocess    import reimport osimport timeimport thread  #(1)工程位置projectPath="D:\/hao123\/code\/client-android"#(2)lint输出txt记录文件txt="D:\/hao123_unused_res.txt"#(3)正则表达式,清除drawable和layout下多余的jpg/png/xml,#   并且排除以sailor_|wenku_|zeus_|bdsocialshare_|floating_life_|weather_info_icon_|anthology_开头的文件regex = re.compile(r"^res\\(drawable(-land)?(-[xn]?[mhlo](dpi))|layout)?\\(?!(sailor_|wenku_|zeus_|bdsocialshare_|floating_life_|weather_info_icon_|anthology_))[0-9a-zA-Z_\.]*\.(jpg|png|xml)", re.IGNORECASE)#(4)lint.bat的位置lint="D:\/sdk\/tools\/lint.bat"isgotTxt=Falsedef timer(interval):      while not isgotTxt:        print 'Lint is analyzing: %s'%time.ctime()          time.sleep(interval)if not os.path.exists(txt):    thread.start_new_thread(timer, (5,))    cmd=lint+' --check "UnusedResources" "'+ projectPath +'" >'+txt    p = subprocess.Popen(cmd, shell = True,stdout = subprocess.PIPE,stdin = subprocess.PIPE,stderr = subprocess.PIPE)            p.wait()fobj=open(txt,'r') isgotTxt=Truei=0j=0for line in fobj:    #print str(i)+":"+line    match=regex.match(line)    if match:        i=i+1        filename=projectPath+"\/"+match.group().replace('\\',"\\/")        try:            print filename            os.remove(filename)            j=j+1            print "was deleted!"        except WindowsError:            print "is not exists"            passprint "Total Unused Resources = "+str(i)print "Total deleted Resources = "+str(j)

虽然系统不一样,还是打算写python脚本来试一下。


5.还有这几篇有关与AndroiStudio图形化操作 以及一个Android Clear工具,以及用jar的方式都大同小异了,下面做个总结,下面几篇文章也是有不同的帮助

多方法批量删除Android中无用的资源(更新Android Studio2.1工具) 去除无用资源文件最方便的方法

清除Android工程中没用到的资源 去除无用java代码

清理你的Android代码

找出代码中已有的BUG —— FindBugs

去掉多余的jar包 —— ClassPath Helper

一定要非常注意的点:

(1)被无用资源引用的资源不会被视为无用资源,所以需要重复执行多次,保证清除干净。

(2)删除资源文件之前要先删除无用java代码,否则容易报错,因为代码中还(可能)存在引用.

(3)一定要提交之后,再做备份在清除资源,你懂~


我的思路

1. 清除Java代码

2. 找出无用资源

3. 按需清理

具体如下:

清除Java代码

  • 安装Eclipse的UCDetector插件,对工程执行检查,结果会输出到一个文本文件中,同样是每个问题一行.
  • 处理没用到的类文件
String reportPath = "**/ucdetector_reports/UCDetectorReport_001.txt";BufferedReader reader = new BufferedReader(new FileReader(reportPath));String line;int count = 0;while((line = reader.readLine()) != null) {    if (line.contains("Class") && line.contains("has 0 references") && !line.contains("Method")[ && other conditions]) {        count++;        int end = line.indexOf(".");        if (end != -1){            String className = line.substring(0, end);            System.out.println(className);        }    }}
  • 过滤不想删除的

找出无用资源 && 按需清理

在最新的版本(Studio2.1)中,lint已经可以自行删除无用资源,这样的话,我们的python脚本也不需要写了(2.1以下还是自行写脚本),具体操作如下:

  • Ctrl+Shift+Alt+I 弹出一个框,输入UnusedResources,弹出下图

  • 点击OK,出来下图

我们选择Remove All Unused Resources。片刻后(工程大可能会比较久,1-2min?)弹出一个确认对话框,确认之 。


上述提到的LINT:

静态代码分析工具,无需运行,无需测试用例

扫描整个项目,分析以下潜在的问题,分类指出问题描述、问题位置,并提供合理的修改建议(这是才是关键啊,不管有木有大问题,看看这些问题及描述,也能过把瘾啊):

1)性能 布局性能(以前是 layoutopt工具,可以解决无用布局、嵌套太多、布局太多、overdraw) 其他性能(如:draw/layout 时进行对象的声明等)

2)未使用到资源、资源缺少(不同资源的适配)

3)有更高性能的资源替换 ---- eg:SparseBooleanArray SparseIntArray

4)国际化问题(硬编码)

5)图标的问题(重复的图标,错误的大小)

6)可用性问题(如不指定的文本字段的输入型)

7)manifest文件的错误 -- 未注册activity service等等

8)内存泄露 --- 如:handle的不当使用 。

9)占内存的资源及时回收 --- 如:TypedArray未回收资源等

附:

Android性能优化之LINT使用总结

Improve Your Code with Lint google文档

更多相关文章

  1. Android(安卓)图片资源的异步加载2
  2. Android优秀开发资源
  3. 4.1 Android如何访问资源
  4. android 学习资源收藏备份
  5. Android(安卓)使用 array.xml
  6. android 添加和删除快捷方式
  7. Mac端完全删除Android(安卓)Studio
  8. API 25 (Android(安卓)7.1.1 API) widget.ProgressBar——属性分
  9. android 根据Bitmap bitmap 保存图片到手机上

随机推荐

  1. 【Android个人理解(一)】通过Looper与Handl
  2. Android面试真题,了解一下?
  3. android缓存设计
  4. Gradle Android最新自动化编译脚本教程(
  5. 【设计模式与Android】单例模式——独一
  6. Android中点击空白区域控件自动隐藏(事件
  7. 如何解决本地大批量数据的更新,和后台的同
  8. Android基础知识巩固系列 Android之四大
  9. android地图技术文档
  10. Android…又摸出来玩了下。