如何在使用eclipse的情况下,清理android项目中的冗余class文件和资源文件以及冗余图片
在我们迭代项目的过程中,经常会启用某些功能,或者修改某些界面的问题,那么问题来了,这样很容易出现大量的冗余.java文件,冗余资源文件,一些冗余的界面文件等。那么问题既然出现了,那么如何去解决呢,这就是今天着重要去解决的问题?
first:
eclipse有个检查冗余java文件的插件,名叫UCDetector:
下载地址为:http://sourceforge.net/projects/ucdetector/files/latest/download?source=files
官网地址:http://www.ucdetector.org/index.html
一些使用方法:下载完后,将下载的jar文件放置在\eclipse\dropins文件夹下面,然后重新启动eclipse即可安装完这个插件。
一下是从其他网站复制的这个工具使用的截图:
阿西吧,不能直接粘贴人家的图片,擦,还是给个链接地址吧:http://www.jb51.net/softjc/123402.html
当然你可以根据提示,删除冗余的java文件(推荐这种,比较谨慎点,万一那个类你不想删呢);除了这种,还有另外一种更加炫计的方法:
https://github.com/jasonross/Android-CU(果然github上好多好东东,过多推荐)
一下是readme.md文件中的简介:
CU是clear unused的缩写,本项目主要用来清理Android工程中无用的代码文件和资源文件。
CURes.java
用于清理资源文件,借助于ADT SDK自带的lint工具,相对路径为\sdk\tools\lint.bat。
CUSrc.java
用于清理.java文件,需要Eclipse插件UCDetector配合。
使用
清除无用文件,需要交替运行CURes.java
和CUSrc.java
,直到没有可删除文件为止。
运行CURes.java
- 运行参数为lint.bat文件绝对路径和android工程目录,如
D:adt/sdk/tools/lint.bat D:/nova
。 String[] dirArray
为要删除资源文件的相对目录,默认为res目录下。一般来说,values
不需要删除,故不添加。- 运行结果保存在当前目录下,文件名为格式化后的时间戳。
运行CUSrc.java
- 设置UCDetector,忽略不需要扫描的文件,如Activity
- 使用UCDetector扫描项目生成txt报告
- 运行程序需要两个参数,UCDetector生成的报告路径,项目的路径,如
D:/UCDetector/report.txt D:/nova
- 运行结果会保存在当前目录下的UnusedJava.txt文件中。
注意
- 清除资源时,如果使用字符串形式调用layout等资源文件,无法被lint识别,会造成误删。
- 清除代码时,如果使用字符串形式调用fragment等控件或者使用反射时,无法被UCDetector识别,会造成误删。
其实项目中有三个java文件,一个CURes.java,一个CUSrc.java,还有ClearDrawble.java文件
来来来,先看下人家是怎么干的:
CURes.java
import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.text.SimpleDateFormat; import java.util.Date; public class CURes { public static final String separator = File.separator; //这里是清理无用res文件的方法,使用到了lint.bat工具
public static void clearRes(String lintPath, String projectPath, String[] dirArray) { Process process = null; InputStream is = null; InputStreamReader isr = null; BufferedReader br = null; FileWriter fw = null;
//使用到了lint.bat工具检索项目中无用的资源文件
String cmd = lintPath + " --check UnusedResources " + projectPath; int fileCount = 0, singleCount; long fileSize = 0; try {
//生成日志文件,主要记录删除那些无用的资源文件
SimpleDateFormat formatter = new SimpleDateFormat("CURes-yyyy-MM-dd-HH-mm-ss"); Date curDate = new Date(System.currentTimeMillis()); String dateStr = formatter.format(curDate); fw = new FileWriter(dateStr + ".txt", true); Runtime runtime = Runtime.getRuntime(); String line = null; do { singleCount = 0;
//执行lint无用资源文件
process = runtime.exec(cmd); is = process.getInputStream(); isr = new InputStreamReader(is); br = new BufferedReader(isr); while ((line = br.readLine()) != null) { boolean needDel = false; for (String dir : dirArray) { if (line.startsWith("res" + separator + dir)) { needDel = true; break; } } if (needDel) { int index = line.indexOf(":"); if (index > 0) { String filePath = projectPath + separator + line.substring(0, index); ++fileCount; ++singleCount; File file = new File(filePath); fileSize += file.length(); //删除无用资源文件的代码
boolean success = file.delete(); System.out.println(filePath + " " + success); fw.write(filePath + " " + success + "\n"); fw.flush(); } } } } while (singleCount != 0); String result = "delete file " + fileCount + ",save space " + fileSize / 1024 + "KB."; System.out.println(result); fw.write(result); fw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (fw != null) { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } if (process != null) { process.destroy(); } } } public static void main(String[] args) {
//一下三行可以删除,没用
if (args.length < 2) { System.out.println("Please config program arguments. Correct arguments contain both absolute path of lint.bat and that of android project."); return; }
//删除无用资源文件的的重要代码,请注意,lintPath值得是你的lint.bat文件地址,记得把╲╲换成/,否则会出现问题,projectPath是值得你的android项目地址
//一下args[0] args[1]代码都可以替换为stirng内容的地址
String lintPath = args[0]; String projectPath = args[1]; String[] dirArray = { "drawable", "layout", "anim", "color" }; CURes.clearRes(lintPath, projectPath, dirArray); } }
ok,然后我们看看如何删除无用.java文件的:
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.RandomAccessFile; public class CUSrc {
//注意此处代码是清理无用java文件的,逻辑分下往下继续走
private static String clearUnusedJavaFile(String inFileName, String localProjectPath) throws IOException { File infile = new File(inFileName);
//生成无用代码的日志文件
RandomAccessFile outfile = new RandomAccessFile("UnusedJava.txt", "rw"); int index = -1;
//分析项目中src文件夹下面的无用资源文件,localProjectPath为android项目的绝对路径
String path = localProjectPath + "/src/"; BufferedReader bf = new BufferedReader(new FileReader(infile)); String content = ""; StringBuilder sb = new StringBuilder(); while ((content = bf.readLine()) != null) { index = content.indexOf(".<init>"); if (index != -1 && (content.indexOf("\tClass") == (content.indexOf(")") + 1) || content.indexOf("\tInterface") == (content.indexOf(")") + 1))) { String temp = path + content.substring(0, index).replace('.', '/') + ".java";
//删除冗余代码,并生成日志文件内容
sb.append(temp).append("\t" + new File(temp).delete()).append( "\t" + System.currentTimeMillis()).append("\r\n"); } } outfile.seek(outfile.length()); outfile.writeBytes(sb.toString()); bf.close(); outfile.close(); return sb.toString(); } public static void main(String[] args) { // TODO Auto-generated method stub if (args.length == 2) { String inputFile = args[0]; String localProjectPath = args[1]; try { String str = clearUnusedJavaFile(inputFile, localProjectPath); System.out.print(str); } catch (IOException e) { // TODO Auto-generated catch block System.out.print("something wrong"); } } else { System.out.println("arguments wrong!!"); } } }
分析完毕,吃饭去喽。
2016年3月31日23:54:35更新
阿里有关apk瘦身的博文,分享链接:
http://www.cnblogs.com/alisecurity/p/5341218.html