初探Matrix Android ApkChecker
- 2022 年 2 月 16 日
- 筆記
- Android, Open source tool
背景
因為我所在的項目是做投放包,對安卓包的大小很敏感,經常會優化包的大小,所以想引入工具靜態檢測包大小,看能不能找到其中可以優化的地方,防患於未然。Matrix是微信終端自研和正在使用的一套APM(Application Performance Management)系統。 Matrix-ApkChecker作為Matrix系統的一部分,是針對android安裝包的分析檢測工具,根據一系列設定好的規則檢測apk是否存在特定的問題,並輸出較為詳細的檢測結果報告,用於分析排查問題以及版本追蹤。Matrix-ApkChecker以一個jar包的形式提供使用,通過命令行執行 java -jar ApkChecker.jar 即可運行。
Matrix-ApkChecker的使用
在git上下載matrix-apk-canary-0.4.10.jar
直接在命令行執行
java -jar ApkChecker.jar
即可以查看Matrix-ApkChecker的使用說明 (注意:下面所說的路徑為完整路徑,非相對路徑)
Matrix-ApkChecker的命令行參數比較多,主要包括global參數和option參數兩類:
- global
--apk 輸入apk文件路徑(默認文件名以apk結尾即可)
--mappingTxt 代碼混淆mapping文件路徑 (默認文件名是mapping.txt)
--resMappingTxt 資源混淆mapping文件路徑(默認文件名是resguard-mapping.txt)
--input 包含了上述輸入文件的目錄(給定--input之後,則可以省略上述輸入文件參數,但上述輸入文件必須使用默認文件名)
--unzip 解壓apk的輸出目錄
--output 輸出結果文件路徑(不含後綴,會根據format決定輸出文件的後綴)
--format 結果文件的輸出格式(例如 html、json等)
--formatJar 實現了自定義結果文件輸出格式的jar包
--formatConfig 對結果文件輸出格式的一些配置項(json數組格式)
global 參數之後緊跟若干個 Option,這些 Option 是可選的,一個 Option 表示針對 apk 的一個檢測選項。
- option參數
- manifest 從AndroidManifest.xml文件中讀取apk的全局信息,如packageName、versionCode等。
- fileSize 列出超過一定大小的文件,可按文件後綴過濾,並且按文件大小排序
--min 文件大小最小閾值,單位是KB --order 按照文件大小升序(asc)或者降序(desc)排列 --suffix 按照文件後綴過濾,使用","作為多個文件後綴的分隔符
- countMethod 統計方法數
group 輸出結果按照類名(class)或者包名(package)來分組
- checkResProguard 檢查是否經過了資源混淆 (AndResGuard)
- findNonAlphaPng 發現不含alpha通道的png文件
- checkMultiLibrary 檢查是否包含多個ABI版本的動態庫
- uncompressedFile 發現未經壓縮的文件類型(即該類型的所有文件都未經壓縮)
suffix 按照文件後綴過濾,使用","作為多個文件後綴的分隔符
- countR 統計apk中包含的R類以及R類中的field count
- duplicatedFile 發現冗餘的文件,按照文件大小降序排序
- checkMultiSTL 檢查是否有多個動態庫靜態鏈接了STL
- unusedResources 發現 apk 中包含的無用資源
rTxt R.txt文件的路徑(如果在全局參數中給定了--input,則可以省略) ignoreResources 需要忽略的資源,使用","作為多個資源名稱的分隔符
- unusedAssets 發現apk中包含的無用assets文件
- ignoreAssets 需要忽略的assets文件,使用”,”作為多個文件的分隔符
- unstrippedSo 發現apk中未經裁剪的動態庫文件
除了直接在命令行中帶上詳細參數外,也可以將參數配置以 json 的格式寫到一個配置文件中,然後在命令行中使用
指定配置文件的路徑。一個典型的配置文件格式如下:
{
"--apk": "/xxx",
"--formatConfig": [
{
"group": [
{
"name": "Android System",
"package": "android"
},
{
"name": "java system",
"package": "java"
},
{
"name": "xxx",
"package": "com.xxx"
}
],
"name": "-countMethod"
}
],
"--format": "mm.html,mm.json",
"options": [
{
"name": "-manifest"
},
{
"--suffix": "png, jpg, jpeg, gif, arsc",
"--min": "10",
"name": "-fileSize",
"--order": "desc"
},
{
"--group": "package",
"name": "-countMethod"
},
{
"name": "-checkResProguard"
},
{
"--min": "10",
"name": "-findNonAlphaPng"
},
{
"name": "-checkMultiLibrary"
},
{
"--suffix": "png, jpg, jpeg, gif, arsc",
"name": "-uncompressedFile"
},
{
"name": "-countR"
},
{
"name": "-duplicatedFile"
},
{
"name": "-unusedAssets",
"--ignoreAssets": [
"*.so"
]
}
],
"--output": "/xxx"
}
其中,mm.html 和 mm.json 是微信使用的自定義輸出格式,Matrix-ApkChecker 默認提供 html 、json、mm.html 以及 mm.json 四種輸出格式。
要注意的是所有路徑都必須是絕對路徑,如果是windows系統的話複製文件夾的路徑是反斜杠(),會報轉義錯誤,改為正斜杠(/)
使用配置文件命令如下:
java -jar matrix-apk-canary-0.4.10.jar --config 配置文件路徑
輸出這麼一串代碼就代表執行成功
Matrix-ApkChecker的功能
- 讀取manifest的信息
從AndroidManifest.xml文件中讀取apk的全局信息,如packageName、versionCode等
- 按文件大小排序列出apk中包含的文件
列出超過一定大小的文件,可按文件後綴過濾,並且按文件大小排序
- 統計方法數
統計dex包含的方法數,並支持將輸出結果按照類名(class)或者包名(package)來分組
- 檢查是否經過了資源混淆(AndResGuard)
檢查apk是否經過了資源混淆,推薦使用資源混淆來進一步減小apk的大小
- 搜索不含alpha通道的png文件
對於不含alpha通道的png文件,可以轉成jpg格式來減少文件的大小
- 檢查是否包含多個ABI版本的動態庫
so文件的大小可能會在apk文件大小中占很大的比例,可以考慮在apk中只包含一個ABI版本的動態庫
- 搜索未經壓縮的文件類型
某個文件類型的所有文件都沒有經過壓縮,可以考慮是否需要壓縮
- 統計apk中包含的R類以及R類中的field count
編譯之後,代碼中對資源的引用都會優化成int常量,除了R.styleable之外,其他的R類其實都可以刪除
- 搜索冗餘的文件
對於兩個內容完全相同的文件,應該去冗餘
- 檢查是否有多個動態庫靜態鏈接了STL
如果有多個動態庫都依賴了STL,應該採用動態鏈接的方式而非多個動態庫都去靜態鏈接STL
- 搜索apk中包含的無用資源
apk中未經使用到的資源,應該予以刪除
- 搜索apk中包含的無用assets文件
apk中未經使用的assets文件,應該予以刪除
- 搜索apk中未經裁剪的動態庫文件
動態庫經過裁剪之後,文件大小通常會減小很多
示例分析
下面,我們對一個示例apk使用Matrix-ApkChecker進行檢查,並根據檢查的結果進行針對性的減包優化。
從Matrix-ApkChecker的輸出結果中可以看到示例apk的相關全局信息如下圖所示:
示例 apk 中包含的文件按類型統計如下圖所示:
png文件(不包括 .9.png)未經壓縮,可以考慮一定程度的壓縮
存在一些冗餘的文件,文件內容相同的文件應該只保留一份
存在無用資源,包括未使用的系統support包中的資源、第三方資源包中的無用資源以及示例app定義的資源
存在無用的assets資源,應該刪除
後續
了解完Matrix-ApkChecker的基本功能後,後續考慮集成到jenkins中,每次編譯產出Apk時運行腳本記錄apk的總大小值,對比每個版本的包大小總值,dex、so、圖片資源各自佔比、是否有重複資源、是否有圖片未壓縮等,如果能每個版本檢查出上述問題並提出優化建議,那麼在持續集成中價值就比較大
參考
//github.com/Tencent/matrix/wiki/Matrix-Android-ApkChecker