此工具在我的github上。地址:https://github.com/NashLegend/AndroidResourceCleaner

公司主營(yíng)業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。成都創(chuàng)新互聯(lián)公司推出薩嘎免費(fèi)做網(wǎng)站回饋大家。
很多人都知道androidunusedresources.jar這個(gè)工具,它可以把Android項(xiàng)目中無(wú)用的資源列出來(lái)。然而它所做的也就止于此了,在列出所有的無(wú)用資源以后,開(kāi)發(fā)者們還得手動(dòng)刪除這些文件,這實(shí)在是一個(gè)沒(méi)技術(shù)含量卻又煩人的體力活,作為程序員,自然是有解決辦法的,我們?yōu)槭裁床粚懸粋€(gè)程序,讓程序來(lái)實(shí)現(xiàn)這個(gè)功能呢?有些人給出了部分解決方案,就是清除部分無(wú)用資源,比如layout和drawable,因?yàn)檫@種資源是和文件一一對(duì)應(yīng)的,只要?jiǎng)h除對(duì)應(yīng)文件就可以實(shí)現(xiàn)資源的清理,但是對(duì)于其他沒(méi)用到的如string、style等資源卻沒(méi)有處理。而本文的工具則彌補(bǔ)了這個(gè)缺點(diǎn),可以清理所有的資源文件。
這個(gè)功能要實(shí)現(xiàn)的功能應(yīng)該是這樣的:
1、讀取androidunusedresources.jar導(dǎo)出的無(wú)用資源列表。
2、清理無(wú)用的資源,包括刪除無(wú)用文件以及修改包含無(wú)用資源的文件。
對(duì)于drawable和layout等資源,當(dāng)然是直接刪掉文件就行了,因?yàn)橐粋€(gè)文件就對(duì)應(yīng)著一個(gè)資源,而對(duì)于其他的資源就不是這么一回事了,一個(gè)文件里面可能有很多資源,所以只能是刪除文件里面的一部分,而保留另一部分。
程序大體如下:
首先是main
public static void main(String[] args) {
if (args.length > 0) {
unusedCleaner(args[0]);
}
}調(diào)用了unusedCleaner方法,我們就用這個(gè)方法清理無(wú)用資源,傳入的參數(shù)是androidunusedresources.jar導(dǎo)出的無(wú)用資源文件列表。
然后看unusedCleaner方法。
// currents是在找到下一個(gè)文件前列出的所有資源id。因?yàn)橐粋€(gè)文件可能對(duì)應(yīng)著多個(gè)id,有可能是一個(gè)多對(duì)多的關(guān)系。
static ArrayList<TypeSource> currents = new ArrayList<>();
static boolean LastIsPath = false;
public static void unusedCleaner(String filePath) {
ArrayList<TypeSource> files = new ArrayList<>();//待清理資源列表
try {
File file = new File(filePath);//androidunusedresources導(dǎo)出的無(wú)用資源文件列表
if (file.isFile() && file.exists()) {
InputStreamReader read = new InputStreamReader(
new FileInputStream(file), "utf-8");
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = null;
while ((lineTxt = bufferedReader.readLine()) != null) {
if (!parseType(lineTxt)) {
//逐行讀取數(shù)據(jù),并提取數(shù)據(jù)。parseType方法可以判斷是否此行代表發(fā)現(xiàn)了資源名。對(duì)應(yīng)的格式如drawable: bg_list
//如果不是的話,那么這一行就有可能是資源所對(duì)應(yīng)的文件。
String trim = lineTxt.trim();
if (new File(trim).exists()) {
//簡(jiǎn)單的用文件是否存在判斷此行到底是不是一個(gè)文件名,如果是的話,說(shuō)明currents列表中所有對(duì)應(yīng)的資源名肯定包含在這個(gè)文件里
//就把它添加到一個(gè)待清理的資源列表中,將這些資源和文件對(duì)應(yīng)起來(lái),并添加到待清理列表中
for (Iterator<TypeSource> iterator = currents
.iterator(); iterator.hasNext();) {
TypeSource typeSource = (TypeSource) iterator
.next().clone();
typeSource.path = trim;
typeSource.xmlTag = typeSource.getXmlTag();
files.add(typeSource);
}
LastIsPath = true;
} else {
continue;
}
}
}
read.close();
} else {
System.out.println("noFile");
}
} catch (Exception e) {
System.out.println("Failed");
e.printStackTrace();
}
//全部找出來(lái)后,將這些資源一一清理就是了,清理文件是TypeSource的方法,TypeSource類代表一個(gè)資源。
for (Iterator<TypeSource> iterator = files.iterator(); iterator
.hasNext();) {
TypeSource typeSource = (TypeSource) iterator.next();
System.out.println(typeSource);
typeSource.cleanSelf();
}
System.out.println("done");
}
public static boolean parseType(String lineTxt) {
//判斷當(dāng)前行是不是一個(gè)資源名。如果是的話,加入到currents中,如果上一個(gè)資源是文件,那么清空currents,因?yàn)橹癱urrents中的已經(jīng)加入了待清理列表
String reg = "((drawable)|(layout)|(dimen)|(string)|(attr)|(style)|(styleable)|(color)|(id)|(anim))\\s*:\\s*(\\S+)";
Matcher matcher = Pattern.compile(reg).matcher(lineTxt);//使用正則匹配當(dāng)前行
if (matcher.find()) {
if (LastIsPath) {
currents.clear();
}
LastIsPath = false;
TypeSource typeSource = new TypeSource();
typeSource.type = matcher.group(1);
typeSource.name = matcher.group(12);
currents.add(typeSource);
return true;
} else {
return false;
}
}
static class TypeSource {
String type = "";// 類型
String name = "";// xml中的name屬性
String xmlTag = "";// xml的tag名
String path = "";// 屬于哪個(gè)文件
public String getXmlTag() {
if ("styleable".equals(type)) {
return "declare-styleable";
} else {
return type;
}
}
@Override
public String toString() {
return type + " | " + name + " | " + xmlTag + " | " + path;
}
/**
* 一個(gè)一個(gè)的單獨(dú)刪,反正很快,就不考慮效率了。如果把一個(gè)文件對(duì)應(yīng)的所有資源列出來(lái)統(tǒng)一刪除應(yīng)該很快,但是這里偷懶了
*/
public void cleanSelf() {
try {
if (type == null) {
return;
}
if (type.equals("drawable") || type.equals("layout") || type.equals("anim")) {
new File(path).delete();
} else if (type.equals("id") || type.equals("")) {
// 跳過(guò)了id資源,如果要?jiǎng)h除的話,跟deleteNodeByName方法差不多。
} else {
//deleteNodeByName方法刪除xml中單個(gè)資源項(xiàng)。
deleteNodeByName(path, xmlTag, name);
}
} catch (Exception e) {
}
}
public TypeSource clone() {
TypeSource ts = new TypeSource();
ts.type = type;
ts.name = name;
ts.xmlTag = xmlTag;
ts.path = path;
return ts;
}
}
@SuppressWarnings("unchecked")
public static void deleteNodeByName(String path, String tag, String name) {
//刪除xml文件中的某個(gè)資源項(xiàng)
try {
SAXReader reader = new SAXReader();
Document document = reader.read(new File(path));
Element element = document.getRootElement();
List<Element> list = element.elements(tag);
for (int i = 0; i < list.size(); i++) {
Element ele = list.get(i);
String tName = ele.attributeValue("name");
if (tName != null && tName.length() > 0) {
if (name.equals(ele.attributeValue("name"))) {
element.remove(ele);
break;
}
}
}
OutputFormat format = new OutputFormat("", false);//
XMLWriter xmlWriter = new XMLWriter(new FileWriter(path), format);
xmlWriter.write(document);
xmlWriter.flush();
} catch (Exception e1) {
e1.printStackTrace();
}
}然后導(dǎo)出成jar,使用方法如下
java -jar AndroidUnusedResources.jar >del.txt java -jar cleaner.jar del.txt
好了,原來(lái)幾小時(shí)搞定的事現(xiàn)在只要幾秒鐘了。
由于被無(wú)用資源引用的資源不會(huì)被視為無(wú)用資源,所以要多執(zhí)行幾遍上面的命令才能真正清除掉
注意由于androidunusedresources導(dǎo)出的結(jié)果并不十分準(zhǔn)確,有可能出錯(cuò),所以會(huì)導(dǎo)致清理有可能不準(zhǔn)確。可能會(huì)漏掉某些資源刪除不了。這時(shí)候就得動(dòng)手了。
最后,記得的清理資源前先把代碼提交一下,你懂的
當(dāng)前文章:一個(gè)自動(dòng)清理Android項(xiàng)目無(wú)用資源的工具類及源碼
分享鏈接:http://chinadenli.net/article38/goiesp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、服務(wù)器托管、網(wǎng)站設(shè)計(jì)公司、軟件開(kāi)發(fā)、手機(jī)網(wǎng)站建設(shè)、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)