清除Android工程中没用到的资源

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

清理资源文件

要清理没用的资源,首要的工做固然是找到他们,咱们知道Anroid SDK中有一个工具叫lint,能够帮助咱们查看工程中存在的问题,其中有一项功能就是查找没用到的资源,这样这一步就简单了,直接对须要清理的工程执行如下命令:app

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行,这种事情,固然是交给计算机解决了。code

仔细看生成的文本中的内容会发现结果是按行输出的,每一个问题是单独的一行,并且每一行中的内容也颇有规律xml

file_path[:line]: Warning: info [UnusedResources}ip

因此仍是能够很方便地获得哪一个文件甚至哪行有问题的,我处理的时候只清理了没用的文件,像上面的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相关的信息),每一行":"前的字符串就是文件名,找到了文件名就好处理了,直接删除,或者打印出来,或者写到一个文件里以再次确认是否确认要删除,当把结果写到一个文件后咱们就能够查看这个文件是否有如今没用到但仍不想删除的文件,若是有,处理方法也很简单,去掉这一行或简单地作个标记,如前面打#,而后再读取这个文件把没作标记的行对应的文件删除就好了。字符串

看起来很简单,可是有几点须要注意:

  1. 有些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开头的文件。
  2. lint的分析貌似是不彻底准确的,或者说不够智能,好比有一个drawable只被一个layout引用,而这个layout又是Unused的,lint可能不会发现这个drawable是Unused,这就须要咱们屡次重复执行前面的步骤,直到count为0。
  3. 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条件中过滤掉就行了,也可能本身的一些文件暂时没用到但不想删除,从结果中过滤就行了。

总结

清理资源就两个步骤:

  1. 找到未用到的资源
  2. 按需清理这些资源

经过UCDetectorlint基本上就能够检测到项目中UnusedResource相关的问题了,通常像方法可见性,某个方法没用到这种问题,不处理也罢,改到相应的文件时手工处理算了,主要处理的就是某些文件或类没被用到,有检测报告,分析下报告就好了。这种报告通常是每行报告一个问题而且每行的文字是有规律的(工具生成的确定有规律),按规律过滤出咱们须要的信息就好了

相关文章
相关标签/搜索