如何有效的清除Android中無用的資源(靜態(tài)代碼分析)

誰能告訴我怎么設(shè)置首圖

最近公司要做這個(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 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)目無用資源的工具類及源碼

原文點(diǎn)此處

優(yōu)點(diǎn):把上個(gè)方法中找出的無用資源的信息,再刪除耙厚,整個(gè)步驟封裝成了一個(gè)程序强挫,并且對原GITHUB項(xiàng)目進(jìn)行了優(yōu)化:對用到的如string、style等資源進(jìn)行了處理薛躬。
步驟代碼較長俯渤,就不貼了,詳細(xì)看原文型宝。


3.Android Studio利用Gradle刪除沒有使用到的資源和代碼文件

原文點(diǎn)此處

利用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文檔
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瘟斜,隨后出現(xiàn)的幾起案子缸夹,更是在濱河造成了極大的恐慌痪寻,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虽惭,死亡現(xiàn)場離奇詭異橡类,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)芽唇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門顾画,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人匆笤,你說我怎么就攤上這事研侣。” “怎么了炮捧?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵庶诡,是天一觀的道長。 經(jīng)常有香客問我咆课,道長末誓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任书蚪,我火速辦了婚禮喇澡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘殊校。我一直安慰自己晴玖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布箩艺。 她就那樣靜靜地躺著窜醉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪艺谆。 梳的紋絲不亂的頭發(fā)上榨惰,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機(jī)與錄音静汤,去河邊找鬼琅催。 笑死,一個(gè)胖子當(dāng)著我的面吹牛虫给,可吹牛的內(nèi)容都是我干的藤抡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼抹估,長吁一口氣:“原來是場噩夢啊……” “哼缠黍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起药蜻,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瓷式,失蹤者是張志新(化名)和其女友劉穎替饿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贸典,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡视卢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了廊驼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片据过。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖妒挎,靈堂內(nèi)的尸體忽然破棺而出绳锅,到底是詐尸還是另有隱情,我是刑警寧澤饥漫,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布榨呆,位于F島的核電站,受9級特大地震影響庸队,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜闯割,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一彻消、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宙拉,春花似錦宾尚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锥忿,卻和暖如春牛郑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背敬鬓。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工淹朋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钉答。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓础芍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親数尿。 傳聞我的和親對象是個(gè)殘疾皇子仑性,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,164評論 25 707
  • afinalAfinal是一個(gè)android的ioc,orm框架 https://github.com/yangf...
    passiontim閱讀 15,434評論 2 45
  • 在重慶的那些日子右蹦,每天早上起來诊杆,站立于窗前歼捐,眼前灰蒙蒙的一片。遠(yuǎn)遠(yuǎn)望去刽辙,整個(gè)一霧中城窥岩,沒有一處稀薄,霧氣均勻的籠罩...
    掬手留香閱讀 285評論 4 2
  • 從小到大的生活環(huán)境 造就了我 在沒有過分喧嚷的嘈雜中 也能一心看書 有時(shí)甚至覺得 習(xí)慣成了一種方式 太安靜 反而...
    楓子fengzi閱讀 123評論 0 0