清除Android工程中没用到的资源(转)
项目需求一改再改,UI一调再调,结果就是项目中一堆已经用不到但却没有清理的垃圾资源,不说工程大小问题,对新进入项目的人或看其他模块的代码的人来说,这些没清理的资源可能也可能会带来困扰,所以最好还是清理掉这些垃圾,对于一个稍微大一点的工程来说,手工清理明显是不现实的,这就需要一个方法做这些事情。
清理资源文件
要清理没用的资源,首要的工作当然是找到他们,我们知道Anroid SDK中有一个工具叫lint,可以帮助我们查看工程中存在的问题,其中有一项功能就是查找没用到的资源,这样这一步就简单了,直接对需要清理的工程执行以下命令:
lint --check "UnusedResources" [project_path] > result.txt
执行完以上命令后工程中关于UnusedResources的问题就都保存到result.txt了,先来看一下result.txt的内容
res/values/arrays.xml:202: Warning: The resource R.array.msg_my_friend_category_items appears to be unused [UnusedResources] ^M ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ res/layout/back_up_level_list.xml: Warning: The resource R.layout.back_up_level_list appears to be unused [UnusedResources] res/layout/backup_list.xml: Warning: The resource R.layout.backup_list appears to be unused [UnusedResources] res/layout/backup_listview_item.xml: Warning: The resource R.layout.backup_listview_item appears to be unused [UnusedResources]
可以看到列出了没用到的layout及没用到的values值等信息。有了这些信息,接下来需要做的就是分析这些信息了,手工分析不太现实,因为这个文件可能会非常大,比如我执行上述命令后文件就有2212行,这种事情,当然是交给计算机解决了。
仔细看生成的文本中的内容会发现结果是按行输出的,每个问题是单独的一行,而且每一行中的内容也很有规律
file_path[:line]: Warning: info [UnusedResources}
所以还是可以很方便地得到哪个文件甚至哪行有问题的,我处理的时候只清理了没用的文件,像上面的res/values/arrays.xml:202就没有管,下面看下怎么清除没用到的资源文件。
String projectPath = "***";
BufferedReader reader = new BufferedReader(new FileReader("/home/angeldevil/result.txt"));
String line;
int count = 0;
while((line = reader.readLine()) != null) {
    if (line.contains("UnusedResources") && !line.contains("res/value") && !line.contains("appcompat")) {
        count++;
        int end = line.indexOf(":");
        if (end != -1){
            String file = line.substring(0, end);
            String f = projectPath +file;
            System.out.println(f);
            new File(f).delete();
        }
    }
}
程序非常简单,就几行代码,就是读取result.txt文件的每一行,根据自己需要的条件过滤掉不需要处理的行(比如我只想清理anim、drawable及layout,所以过滤掉res/value目录下的信息,并且忽略appcompat相关的信息),每一行":"前的字符串就是文件名,找到了文件名就好处理了,直接删除,或者打印出来,或者写到一个文件里以再次确认是否确认要删除,当把结果写到一个文件后我们就可以查看这个文件是否有现在没用到但仍不想删除的文件,如果有,处理方法也很简单,去掉这一行或简单地做个标记,如前面打#,然后再读取这个文件把没做标记的行对应的文件删除就行了。
看起来很简单,但是有几点需要注意:
- 有些layout文件,可能你之前用了他们,并在相应的Java文件中用了这个layout布局中的id,如对某些ID的控件设置了onClickListener,并在onClick的switch...case中引用了这些ID,但最后又不用这个Layout了,这时这个layout就是UnusedResource,但是以前引用它的Java代码中对这个layout中的某些ID的引用还没清除,此时删掉这个Layout就会报错,你可以选择清理报错的Java代码,因为它们其实时Dead Code。或者每次清理一部分资源文件,如先清理layout,再清理drawable,对于每一项也可以根据文件名的规则每次再清理一小部分,如只清理res/layout中以item_of开头的文件。
 - lint的分析貌似是不完全准确的,或者说不够智能,比如有一个drawable只被一个layout引用,而这个layout又是Unused的,lint可能不会发现这个drawable是Unused,这就需要我们多次重复执行前面的步骤,直到count为0。
 - lint只能分析资源文件,即res目录下的文件,如果要分析Java文件还需要其他方法,而且,有可能某个资源文件被某Java文件引用,而这个Java文件又是Unused,这样这个资源文件就会逃过lint的检查,所以我们最好先清理了Java文件再清理资源文件。
 
清理Java文件
首先还是要找到未用到的文件,还是利用工具,我用的是UCDetector,即Unused Code Detector,使用方法就不说了,直接Google一下。
安装Eclipse的UCDetector插件,对工程执行检查,这个需要的时间可能会很长,我当时检查了两个小时。。同lint一样,结果会输出到一个文本文件中,同样是每个问题一行,所以只要行分析就行了,比如这样:
com..SampleAdapter.(SampleAdapter.java:18) Class "SampleAdapter" has 0 references SampleAdapter org.ucdetector.analyzeMarkerReference com..SampleAdapter.(SampleAdapter.java:56) Change visibility of Member class "SampleAdapter.ViewHolder" to private - May cause compile errors! SampleAdapter.ViewHolder org.ucdetector.analyzeMarkerVisibilityPrivate
可以看到,检测结果中包含很多信息,如某个类没被用到,某个方法的可见性太大等,同样的,现在只处理没用到的类文件,其他不管了。
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(".<init>");
        if (end != -1){
            String className = line.substring(0, end);
            System.out.println(className);
        }
    }
}
通过以上代码基本上就能找到没用到的类了,还是建议不直接删除而是把结果输出出来,因为结果输出来以后你会发现很多文件你是不想删除的,如:
com.nostra13.universalimageloader.core.assist.DiscCacheUtil.(DiscCacheUtil.java:31) Class "DiscCacheUtil" has 0 references DiscCacheUtil org.ucdetector.analyzeMarkerReference Sergey Tarasevich (nostra13[at]gmail[dot]com)
某些类库中的文件也可能会被检测出来,对于这种直接在if条件中过滤掉就好了,也可能自己的一些文件暂时没用到但不想删除,从结果中过滤就好了。
总结
清理资源就两个步骤:
- 找到未用到的资源
 - 按需清理这些资源
 
通过UCDetector和lint基本上就可以检测到项目中UnusedResource相关的问题了,一般像方法可见性,某个方法没用到这种问题,不处理也罢,改到相应的文件时手工处理算了,主要处理的就是某些文件或类没被用到,有检测报告,分析下报告就行了。这种报告一般是每行报告一个问题并且每行的文字是有规律的(工具生成的肯定有规律),按规律过滤出我们需要的信息就行了
http://www.cnblogs.com/angeldevil/p/3725358.html
清除Android工程中没用到的资源(转)的更多相关文章
- 清除Android工程中没用到的资源
		
项目需求一改再改,UI一调再调,结果就是项目中一堆已经用不到但却没有清理的垃圾资源,不说工程大小问题,对新进入项目的人或看其他模块的代码的人来说,这些没清理的资源可能也可能会带来困扰,所以最好还是清理 ...
 - 利用python自动清除Android工程中的多余资源
		
我们直接在公司项目中使用,效果良好! 分享出脚本代码,希望对Android研发的同学有帮助. 提示,初学python,开发环境是Sublime Text 2,直接Ctrl+B的,其他环境下没调试过.应 ...
 - Lint工具去除Android工程里不再需要的资源
		
摘要: 在项目开发过程中常常会不断改UI设计,于是在定稿要发布的前夕,发现有好多不再需要的资源文件存在,发布的包会把这些无用的资源都包含在里面,造成APK的下载包过大.可以通过Android SDK自 ...
 - 自动删除Android工程中无用的资源
		
开发时间久了, 几个版本迭代之后, 工程中难免留下很多垃圾资源, 造成apk的包很大, 这里介绍一个工具, 可以自动扫描工程中, 没有使用的资源, 然后自动删除: 包括图片, xml, 文本等. 采用 ...
 - [转载]android工程中引入另一个工程中的资源
		
原文地址:android工程中引入另一个工程中的资源作者:87fayuan 在项目中可能遇到这样的问题:项目过大,于是细分为N个子模块来做,每个模块都是不同的工程.涉及到activity传数据时,可以 ...
 - 在android工程中添加图片资源(转加)
		
在Android工程中,每添加一个资源,就会在gen目录下的R.java中自动生成一个新的静态整型变量来指向这个资源.程序文件中调用资源的时候,先在R.java中找到变量名,然后根据变量值查找资源. ...
 - 去掉 Android工程中让人很不爽的“黄色警告”
		
一:问题 二:解决方法 (1)选择android工程,右键Android Tools —> Clear Lint Markers 这种方式能够清除android工程里面的所有警告信息 ...
 - finally不管有没有错都会运行  finally 块用于清除 try 块中分配的任何资源,以及运行任何即使在发生异常时也必须执行的代码
		
finally 块用于清除 try 块中分配的任何资源,以及运行任何即使在发生异常时也必须执行的代码
 - 【Unity与Android】02-在Unity导出的Android工程中接入Google Admob广告
		
我在上一篇文章 [Unity与Android]01-Unity与Android交互通信的简易实现) 中介绍了Unity与Android通讯的基本方法. 这一篇开始进入应用阶段,这次要介绍的是如何在An ...
 
随机推荐
- 在Window和Linux下使用Zthread库
			
ZThread库是一个开源的跨平台高级面向对象的线性和sycnchronization 库,以运行POSIX 和Win32 系统中的C++程序. ZThread库的主页:http://zthread. ...
 - 【IOS实例小计】图像移动--可扩展为动态实现图标变化
			
预备知识: 1.页面切换: 从一个ViewController切换到另一个ViewController有下面几种方法: (1)self.view addSubview:(加载的新页面); 相 ...
 - 腾讯測试project师笔试面试记录
			
从3月29日參加腾讯笔试開始,開始了为期1周的腾讯之旅,尽管最后还是跪在了二面上,可是感觉收获非常多,至少明确了自己与向往的BAT公司的差距,明确了自己还是路漫漫其修远兮. 腾讯非常注 ...
 - thinkphp URL规则、URL伪静态、URL路由、URL重写、URL生成(十五)
			
原文:thinkphp URL规则.URL伪静态.URL路由.URL重写.URL生成(十五) 本章节:详细介绍thinkphp URL规则.URL伪静态.URL路由.URL重写.URL生成 一.URL ...
 - 【错误】expected constructor, destructor, or type conversion before '.' token - 第八个游侠的日志 - 网易博客
			
[错误]expected constructor, destructor, or type conversion before '.' token - 第八个游侠的日志 - 网易博客 [错误]expe ...
 - ANSI Common Lisp 中文翻譯版 — ANSI Common Lisp 中文版
			
ANSI Common Lisp 中文翻譯版 — ANSI Common Lisp 中文版 ANSI Common Lisp 中文翻譯版¶
 - Android笔记二十七.Service组件入门(一).什么是Service?
			
转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.Service 1.Service简单介绍 Service为Android四大组件之中 ...
 - Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架
			
Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的. 历史 Bootstrap 是由 Twitter 的 ...
 - hdu4004(二分)
			
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4004 大致题意 二分最大跳跃能力,判断是否可以在m次内到达对岸! 分析:由于求青蛙最小弹跳能力,所以二 ...
 - Cocos2d-x发展---更改父的颜色、透明度的子节点上
			
标题手段:当我们改变父节点或透明时的颜色.默认是不会影响孩子的节点. 作为交换组看到朋友说可以通过设置相关的参数变化的子节点来实现属性的效果,看了看源代码,记录下来: 引擎版本号为:2. ...