最近公司要做這個(gè)况芒,簡單調(diào)研了一下惜纸,現(xiàn)有的大多數(shù)博客也比較舊了,不太合適绝骚,總結(jié)了這么幾個(gè)方式吧耐版,一起來學(xué)習(xí)下。
為什么要清除Android中這些資源呢
是這樣的压汪,今天收到的郵件里粪牲,有這么一條任務(wù):
資源優(yōu)化
軟件中無用的圖片和布局文件,找到并驗(yàn)證是否無用.
這個(gè)需要設(shè)計(jì)一套工具進(jìn)行分析(自行設(shè)計(jì)最好或者第三方)
嗯,好吧...說笑了! 下面是正題↓↓↓↓
其實(shí)隨著項(xiàng)目不斷更新止剖,需求不斷變動(dòng)腺阳,一改再改,UI一調(diào)再調(diào)穿香,結(jié)果就是項(xiàng)目中一堆已經(jīng)用不到但卻沒有清理的垃圾資源亭引,不說工程大小問題,對新進(jìn)入項(xiàng)目的人或看其他模塊的代碼的人來說扔水,這些沒清理的資源可能也可能會帶來困擾痛侍,所以最好還是清理掉這些垃圾,對于一個(gè)稍微大一點(diǎn)的工程來說魔市,手工清理明顯是不現(xiàn)實(shí)的主届,這就需要一個(gè)方法做這些事情。
知識整合
看了很久待德,總結(jié)了一下君丁,我能找到的市面上規(guī)劃了一下大概有8種方法來做這件事,時(shí)間原因肯定不能全試?yán)步埽驗(yàn)檫x出最合適的方法就要開始寫成公司自己專門的工具了绘闷,簡單說一下:
1.看到的第一個(gè)方法就是用SDK提供的代碼檢查工具Android lint
- Android lint 在 Android sdk tools 當(dāng)中 配好環(huán)境變量(知道了Lint橡庞,這個(gè)工具非常強(qiáng)大!強(qiáng)烈推薦研究一下)
- 輸入:lint --check "UnusedResources" /Users/baozi/Dev/android/android > result.txt(可以把無用資源信息輸出到result文件)
- 打開result文件查看信息印蔗,會發(fā)現(xiàn)在哪一行扒最,叫什么,都會給出相應(yīng)的評價(jià)华嘹。
- 刪除:代碼如下(非常重要)吧趣!借用文中的一句話就是:手工逐條刪除 并不符合程序猿三大優(yōu)秀品質(zhì) : 懶惰 沒有耐心 驕傲
/**
* 刪除 未使用的冗余資源(圖片 xml布局)
*
* @param b
*
* false 顯示資源列表
*
* true 顯示資源列表 并刪除資源
*
* @throws Exception
*/
private static void init(boolean b) throws Exception {
String encoding = "UTF-8"; // 字符格式
String projectPath = "/Users/baozi/Dev/shihui/android/";//Android工程所在地址
String filePath1 = "/Users/baozi";//result的所在路徑
File file = new File(filePath1, "result.txt");//獲取result.txt 文件 生成地址
if (file.isFile() && file.exists()) { // 判斷文件是否存在
InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考慮到編碼格式
BufferedReader bufferedReader = new BufferedReader(read);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
if (line.contains("UnusedResources") && !line.contains("res/value") && !line.contains("appcompat")
&& !line.contains("res/xml")) {
// System.out.println(line);
int end = line.indexOf(":");
if (end != -1) {
String file_end = line.substring(0, end);
String f = projectPath + file_end;
System.out.println(f);
if (b) {
new File(f).delete();
System.out.println("刪除成功");
}
}
}
}
read.close();
}
}
- projectPath : Android工程在硬盤中的位置
- filePath1 : lint 運(yùn)行結(jié)果 result.txt 所在的位置
方法 參數(shù) 傳入false 僅打印結(jié)果 傳入true 打印結(jié)果 并刪除文件
填入正確的地址 就能批量執(zhí)行刪除未使用的 布局 & 圖片 資源 (UnusedResources)
如果想要?jiǎng)h除其它操作 請修改 篩選條件
&& !line.contains("res/xml")```
使用心得: 循環(huán)使用3-6次 能完成 刪除全部未使用的資源 但是有些廢棄的模塊 存在代碼以來關(guān)系 需要手工判斷刪除
缺點(diǎn):判斷不準(zhǔn)確
2.一個(gè)自動(dòng)清理Android項(xiàng)目無用資源的工具類及源碼
優(yōu)點(diǎn):把上個(gè)方法中找出的無用資源的信息,再刪除耙厚,整個(gè)步驟封裝成了一個(gè)程序强挫,并且對原GITHUB項(xiàng)目進(jìn)行了優(yōu)化:對用到的如string、style等資源進(jìn)行了處理薛躬。
步驟代碼較長俯渤,就不貼了,詳細(xì)看原文型宝。
3.Android Studio利用Gradle刪除沒有使用到的資源和代碼文件
利用Gradle來優(yōu)雅的去除沒有用到的資源文件:
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
}
}
}
```
缺點(diǎn):很多沒有用到的類還是會被打包進(jìn)去八匠。去除無效代碼的功能要依賴于混淆,混淆又是一個(gè)耗時(shí)的操作诡曙,還是沒有徹底解決打包慢的問題臀叙。
當(dāng)然也可以做一些忽略無用的代碼優(yōu)化,所以感覺還不錯(cuò)价卤。
--------------------
## 4.利用python自動(dòng)清除Android工程中的多余資源
[原文點(diǎn)此處](http://www.cnblogs.com/kaima/p/3588434.html)
該文是博主直接在公司使用的方法劝萤,如下:
#################################################
環(huán)境: win + python 2.7
作者:馬波
郵箱:mabo02@baidu.com
部門:hao123-無線
說明:首次使用時(shí)lint分析會耗幾分鐘,請耐心等待慎璧。
使用前先clean工程床嫌,確保工程bin下重新生成dex,
以便lint進(jìn)行分析胸私。如果要lint重新分析多余
資源厌处,需要?jiǎng)h掉(2)txt記錄文件,(1)(3)(4)需要
根據(jù)我們的實(shí)際工程手動(dòng)設(shè)置。
如果清除資源后岁疼,工程缺少文件而報(bào)錯(cuò)(極少
情況)阔涉,嘗試通過svn恢復(fù)該文件即可。
#################################################
import subprocess
import re
import os
import time
import thread
(1)工程位置
projectPath="D:/hao123/code/client-android"
(2)lint輸出txt記錄文件
txt="D:/hao123_unused_res.txt"
(3)正則表達(dá)式捷绒,清除drawable和layout下多余的jpg/png/xml瑰排,
并且排除以sailor_|wenku_|zeus_|bdsocialshare_|floating_life_|weather_info_icon_|anthology_開頭的文件
regex = re.compile(r"^res\(drawable(-land)?(-[xn]?mhlo)|layout)?\(?!(sailor_|wenku_|zeus_|bdsocialshare_|floating_life_|weather_info_icon_|anthology_))[0-9a-zA-Z_.]*.(jpg|png|xml)", re.IGNORECASE)
(4)lint.bat的位置
lint="D:/sdk/tools/lint.bat"
isgotTxt=False
def timer(interval):
while not isgotTxt:
print 'Lint is analyzing: %s'%time.ctime()
time.sleep(interval)
if not os.path.exists(txt):
thread.start_new_thread(timer, (5,))
cmd=lint+' --check "UnusedResources" "'+ projectPath +'" >'+txt
p = subprocess.Popen(cmd, shell = True,stdout = subprocess.PIPE,stdin = subprocess.PIPE,stderr = subprocess.PIPE)
p.wait()
fobj=open(txt,'r')
isgotTxt=True
i=0
j=0
for line in fobj:
#print str(i)+":"+line
match=regex.match(line)
if match:
i=i+1
filename=projectPath+"/"+match.group().replace('\',"\/")
try:
print filename
os.remove(filename)
j=j+1
print "was deleted!"
except WindowsError:
print "is not exists"
pass
print "Total Unused Resources = "+str(i)
print "Total deleted Resources = "+str(j)
雖然系統(tǒng)不一樣,還是打算寫python腳本來試一下暖侨。
--------------------
## 5.還有這幾篇有關(guān)與AndroiStudio圖形化操作 以及一個(gè)Android Clear工具椭住,以及用jar的方式都大同小異了,下面做個(gè)總結(jié)字逗,下面幾篇文章也是有不同的幫助
[多方法批量刪除Android中無用的資源(更新Android Studio2.1工具)](http://blog.csdn.net/byszy/article/details/50524816) 去除無用資源文件最方便的方法
[清除Android工程中沒用到的資源](http://www.cnblogs.com/angeldevil/p/3725358.html) 去除無用java代碼
[清理你的Android代碼](http://my.oschina.net/lifj/blog/402541)
[找出代碼中已有的BUG —— FindBugs](http://www.cnblogs.com/kayfans/archive/2012/06/18/2554022.html)
[去掉多余的jar包 —— ClassPath Helper](http://blog.csdn.net/zongxiao08/article/details/8578703)
### **一定要非常注意的點(diǎn):**
**(1)被無用資源引用的資源不會被視為無用資源京郑,所以需要重復(fù)執(zhí)行多次宅广,保證清除干凈。**
**(2)刪除資源文件之前要先刪除無用java代碼些举,否則容易報(bào)錯(cuò)跟狱,因?yàn)榇a中還(可能)存在引用.**
**(3)一定要提交之后,再做備份在清除資源金拒,你懂~**
--------------
# 我的思路
** 1. 清除Java代碼**
** 2. 找出無用資源**
** 3. 按需清理**
具體如下:
** 清除Java代碼**
* 安裝Eclipse的UCDetector插件,對工程執(zhí)行檢查,結(jié)果會輸出到一個(gè)文本文件中兽肤,同樣是每個(gè)問題一行.
* 處理沒用到的類文件
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);
}
}
}
* 過濾不想刪除的
** 找出無用資源 && 按需清理**
在最新的版本(Studio2.1)中,lint已經(jīng)可以自行刪除無用資源绪抛,這樣的話,我們的python腳本也不需要寫了(2.1以下還是自行寫腳本)电禀,具體操作如下:
* Ctrl+Shift+Alt+I 彈出一個(gè)框幢码,輸入U(xiǎn)nusedResources,彈出下圖
![](http://upload-images.jianshu.io/upload_images/2470576-23d82fb97b1763a9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* 點(diǎn)擊OK,出來下圖
![](http://upload-images.jianshu.io/upload_images/2470576-8185a45a030ab7d7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
我們選擇Remove All Unused Resources尖飞。片刻后(工程大可能會比較久症副,1-2min?)彈出一個(gè)確認(rèn)對話框政基,確認(rèn)之 贞铣。
---------------
上述提到的LINT:
靜態(tài)代碼分析工具,無需運(yùn)行沮明,無需測試用例
掃描整個(gè)項(xiàng)目辕坝,分析以下潛在的問題,分類指出問題描述荐健、問題位置酱畅,并提供合理的修改建議(這是才是關(guān)鍵啊,不管有木有大問題江场,看看這些問題及描述纺酸,也能過把癮啊):
>
> 1)性能
布局性能(以前是 layoutopt工具址否,可以解決無用布局餐蔬、嵌套太多、布局太多佑附、overdraw)
其他性能(如:draw/layout 時(shí)進(jìn)行對象的聲明等)
> 2)未使用到資源樊诺、資源缺少(不同資源的適配)
> 3)有更高性能的資源替換 ---- eg:SparseBooleanArray SparseIntArray
> 4)國際化問題(硬編碼)
> 5)圖標(biāo)的問題(重復(fù)的圖標(biāo),錯(cuò)誤的大邪镓摇)
> 6)可用性問題(如不指定的文本字段的輸入型)
> 7)manifest文件的錯(cuò)誤 -- 未注冊activity service等等
> 8)內(nèi)存泄露 --- 如:handle的不當(dāng)使用 啄骇。
> 9)占內(nèi)存的資源及時(shí)回收 --- 如:TypedArray未回收資源等
附:
[Android性能優(yōu)化之LINT使用總結(jié)](http://blog.csdn.net/Rflyee/article/details/43164589)
[Improve Your Code with Lint](https://developer.android.com/studio/write/lint.html) google文檔