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

最近公司要作這個,簡單調研了一下,現有的大多數博客也比較舊了,不太合適,總結了這麼幾個方式吧,一塊兒來學習下。html

爲何要清除Android中這些資源呢

是這樣的,今天收到的郵件裏,有這麼一條任務:java

資源優化python

軟件中無用的圖片和佈局文件,找到並驗證是否無用.
       這個須要設計一套工具進行分析(自行設計最好或者第三方)複製代碼

嗯,好吧...說笑了! 下面是正題↓↓↓↓android

其實隨着項目不斷更新,需求不斷變更,一改再改,UI一調再調,結果就是項目中一堆已經用不到但卻沒有清理的垃圾資源,不說工程大小問題,對新進入項目的人或看其餘模塊的代碼的人來講,這些沒清理的資源可能也可能會帶來困擾,因此最好仍是清理掉這些垃圾,對於一個稍微大一點的工程來講,手工清理明顯是不現實的,這就須要一個方法作這些事情。正則表達式

知識整合

看了好久,總結了一下,我能找到的市面上大概有8種方法來作這件事,以爲裏面比較好用的整理一下分爲5點,時間緣由確定不能全試啦,由於選出最合適的方法就要開始寫成公司本身專門的工具了,簡單說一下:shell

1.看到的第一個方法就是用SDK提供的代碼檢查工具Android lint

Android lint 刪除無用圖片文件和配置文件android-studio

  • Android lint 在 Android sdk tools 當中 配好環境變量(知道了Lint,這個工具很是強大!強烈推薦研究一下)
  • 輸入:lint --check "UnusedResources" /Users/baozi/Dev/android/android > result.txt(能夠把無用資源信息輸出到result文件)
  • 打開result文件查看信息,會發如今哪一行,叫什麼,都會給出相應的評價。
  • 刪除:代碼以下(很是重要)!借用文中的一句話就是:手工逐條刪除 並不符合程序猿三大優秀品質 : 懶惰 沒有耐心 驕傲
/** * 刪除 未使用的冗餘資源(圖片 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 運行結果 result.txt 所在的位置

方法 參數 傳入false 僅打印結果 傳入true 打印結果 並刪除文件性能優化

填入正確的地址 就能批量執行刪除未使用的 佈局 & 圖片 資源 (UnusedResources) app

若是想要刪除其它操做 請修改 篩選條件
if (line.contains("UnusedResources") && !line.contains("res/value") && !line.contains("appcompat") && !line.contains("res/xml")svn

使用心得: 循環使用3-6次 能完成 刪除所有未使用的資源 可是有些廢棄的模塊 存在代碼以來關係 須要手工判斷刪除 缺點:判斷不許確


2.一個自動清理Android項目無用資源的工具類及源碼

原文點此處

優勢:把上個方法中找出的無用資源的信息,再刪除,整個步驟封裝成了一個程序,而且對原GITHUB項目進行了優化:對用到的如string、style等資源進行了處理。 步驟代碼較長,就不貼了,詳細看原文。


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

原文點此處

利用Gradle來優雅的去除沒有用到的資源文件:

android {
        buildTypes {
            release {
                minifyEnabled true
                shrinkResources true
            }
        }
    }複製代碼

缺點:不少沒有用到的類仍是會被打包進去。去除無效代碼的功能要依賴於混淆,混淆又是一個耗時的操做,仍是沒有完全解決打包慢的問題。

固然也能夠作一些忽略無用的代碼優化,因此感受還不錯。


4.利用python自動清除Android工程中的多餘資源

原文點此處

該文是博主直接在公司使用的方法,以下:

#################################################
#環境: win + python 2.7
#做者:馬波
#郵箱:mabo02@baidu.com
#部門:hao123-無線
#說明:首次使用時lint分析會耗幾分鐘,請耐心等待。
# 使用前先clean工程,確保工程bin下從新生成dex,
# 以便lint進行分析。若是要lint從新分析多餘
# 資源,須要刪掉(2)txt記錄文件,(1)(3)(4)須要
# 根據咱們的實際工程手動設置。
# 若是清除資源後,工程缺乏文件而報錯(極少
# 狀況),嘗試經過svn恢復該文件便可。
#################################################
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)正則表達式,清除drawable和layout下多餘的jpg/png/xml,
# 而且排除以sailor_|wenku_|zeus_|bdsocialshare_|floating_life_|weather_info_icon_|anthology_開頭的文件
regex = re.compile(r"^res\\(drawable(-land)?(-[xn]?[mhlo](dpi))|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)複製代碼

雖然系統不同,仍是打算寫python腳原本試一下。


5.還有這幾篇有關與AndroiStudio圖形化操做 以及一個Android Clear工具,以及用jar的方式都大同小異了,下面作個總結,下面幾篇文章也是有不一樣的幫助

多方法批量刪除Android中無用的資源(更新Android Studio2.1工具) 去除無用資源文件最方便的方法

清除Android工程中沒用到的資源 去除無用java代碼

清理你的Android代碼

找出代碼中已有的BUG —— FindBugs

去掉多餘的jar包 —— ClassPath Helper

必定要很是注意的點:

(1)被無用資源引用的資源不會被視爲無用資源,因此須要重複執行屢次,保證清除乾淨。

(2)刪除資源文件以前要先刪除無用java代碼,不然容易報錯,由於代碼中還(可能)存在引用.

(3)必定要提交以後,再作備份在清除資源,你懂~


個人思路

1. 清除Java代碼

2. 找出無用資源

3. 按需清理

具體以下:

清除Java代碼

  • 安裝Eclipse的UCDetector插件,對工程執行檢查,結果會輸出到一個文本文件中,一樣是每一個問題一行.
  • 處理沒用到的類文件
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已經能夠自行刪除無用資源,這樣的話,咱們的python腳本也不須要寫了(2.1如下仍是自行寫腳本),具體操做以下:

  • Ctrl+Shift+Alt+I 彈出一個框,輸入UnusedResources,彈出下圖

  • 點擊OK,出來下圖

咱們選擇Remove All Unused Resources。片刻後(工程大可能會比較久,1-2min?)彈出一個確認對話框,確認之 。


上述提到的LINT:

靜態代碼分析工具,無需運行,無需測試用例

掃描整個項目,分析如下潛在的問題,分類指出問題描述、問題位置,並提供合理的修改建議(這是纔是關鍵啊,無論有木有大問題,看看這些問題及描述,也能過把癮啊):

1)性能 佈局性能(之前是 layoutopt工具,能夠解決無用佈局、嵌套太多、佈局太多、overdraw) 其餘性能(如:draw/layout 時進行對象的聲明等)

2)未使用到資源、資源缺乏(不一樣資源的適配)

3)有更高性能的資源替換 ---- eg:SparseBooleanArray SparseIntArray

4)國際化問題(硬編碼)

5)圖標的問題(重複的圖標,錯誤的大小)

6)可用性問題(如不指定的文本字段的輸入型)

7)manifest文件的錯誤 -- 未註冊activity service等等

8)內存泄露 --- 如:handle的不當使用 。

9)佔內存的資源及時回收 --- 如:TypedArray未回收資源等

附:

Android性能優化之LINT使用總結

Improve Your Code with Lint google文檔

相關文章
相關標籤/搜索