在我們迭代項目的過程中,經常會啟用某些功能,或者修改某些界面的問題,那么問題來了,這樣很容易出現大量的冗余.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