Markdown版本筆記 | 我的GitHub首頁 | 我的博客 | 我的微信 | 我的郵箱 |
---|---|---|---|---|
MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
Android 資源混淆 AndResGuard
目錄
資源混淆工具庫簡介
AndResGuard 是一個幫助你縮小 APK 大小的工具,他的原理類似 Java Proguard
,但是只針對資源
。他會將原本冗長的資源路徑變短
,例如將 res/drawable/activity_advanced_setting_for_test
變為 r/d/a
。
AndResGuard不涉及編譯過程
,只需輸入一個 apk(無論簽名與否,debug版,release版均可,在處理過程中會直接將原簽名刪除),可得到一個實現資源混淆后的 apk(若在配置文件中輸入簽名信息,可自動重簽名並對齊,得到可直接發布的 apk)以及對應資源 ID 的 mapping 文件。
底層原理詳見 WeMobileDev公眾號文章
點擊查看 更多細節和命令行使用方法
已知問題:當時在使用7zip壓縮的APK時,調用AssetManager#list(String path)返回結果的首個元素為空字符串. #162
最佳實踐
- 如果不是對 APK size 有極致的需求,請不要把 resource.asrc 添加進 compressFilePattern. (#84 #233)
- 對於發布於 Google Play 的 APP,建議不要使用 7Zip 壓縮,因為這個會導致 Google Play 的優化 Patch 算法失效. (#233)
因為 andresGuard 只混淆資源,所以可以和阿里百川的 Hotfix 完美集成(2.0以前的hotfix只能熱修復代碼)。
使用
配置 build.gradlle
在 module(app) 中的 build.gradlle 中添加以下代碼:
apply plugin: 'com.android.application'
apply plugin: 'AndResGuard' //應用AndResGuard插件
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.13' //添加AndResGuard依賴
}
}
android {
signingConfigs { //配置簽名信息,注意,要放在buildTypes之前
release {
storeFile file("../keystore/bea.keystore") //簽名文件位置,【.】代表當前目錄,【..】代表父目錄
storePassword "beachinambk"
keyAlias "bea.keystore"
keyPassword "beachinambk"
v2SigningEnabled true
}
debug {
storeFile file("../keystore/debug.keystore")
}
}
buildTypes {
release { //配置構建選項
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
shrinkResources true
zipAlignEnabled true
pseudoLocalesEnabled true
signingConfig signingConfigs.release //簽名文件
}
}
}
//-----------------------------配置 AndResGuard-----------------------------
andResGuard {
mappingFile = null // = file("./resource_mapping.txt") //用於keep住資源的路徑的mapping文件所在路徑
use7zip = true //啟用壓縮。為true時,useSign必須為true
useSign = true // 啟用簽名。為true時,需要配置signConfig
keepRoot = false // 為true時,會keep住所有資源的原始路徑,只混淆資源的名字
whiteList = [ //白名單,支持通配符,【+】代表1個或多個,【?】代表0個或1個,【*】代表0個或多個
"R.mipmap.ic_launcher", "R.drawable.icon",// for your icon
"R.string.com.crashlytics.*",// for fabric,詳見https://docs.fabric.io/android/crashlytics/build-tools.html
"R.string.google_app_id",// for google-services
"R.id.*",//任意id
]
compressFilePattern = [ //需要壓縮的文件的匹配規則,一般這里不需要動。支持 ? + * 通配符
"*.png",
"*.jpg",
"*.jpeg",
"*.gif",
"resources.arsc"
]
sevenzip { //配置7Zip,只需設置 artifact 或 path;支持同時設置,但此時以 path 的值為優先
artifact = 'com.tencent.mm:SevenZip:1.2.13'
//path = "/usr/local/bin/7za" //path指本地安裝的7za(7zip命令行工具)
}
// finalApkBackupPath = "${project.rootDir}/final.apk" //可選,指定生成的apk的保存路徑
// digestalg = "SHA-256" //可選: 指定v1簽名時生成jar文件的摘要算法,默認值為“SHA-1”
}
配置 whiteList 與 mappingFile
默認 andResGuard 會混淆所有資源文件,而白名單則允許我們指定不被混淆的資源文件。
例如友盟、融雲在 sdk 里面寫死了資源名,所以如果被我們混淆之后就找不到指定資源,則運行時就會崩潰。
另外,所有使用 getIdentifier 訪問的資源也都需要加入白名單。
getResources().getIdentifier(“com.test.demo:drawable/icon”,null,null);//包名 : 資源文件夾名 / 資源名
getResources().getIdentifier(“icon”, “drawable”, “com.test.demo”);//ID名,資源屬性,包名
可以在 white_list.md 查看更多第三方 sdk 的白名單配置。
白名單機制只作用於資源的 specsName,不會 keep 住資源的路徑。如果想 keep 住資源的路徑,可以使用 mappingFile。
例如我想 keep 住所有 folder 中的 icon,可以在 mappingFile 指向的文件添加:
res path mapping:
res/mipmap-hdpi-v4 -> res/mipmap-hdpi-v4
res/mipmap-mdpi-v4 -> res/mipmap-mdpi-v4
res/mipmap-xhdpi-v4 -> res/mipmap-xhdpi-v4
res/mipmap-xxhdpi-v4 -> res/mipmap-xxhdpi-v4
res/mipmap-xxxhdpi-v4 -> res/mipmap-xxxhdpi-v4
啟動任務
使用 Android Studio 的同學可以在 andresguard 下找到相關的構建任務,命令行可直接運行./gradlew resguard[BuildType | Flavor],如:
gradlew.bat resguardRelsese //Windows
./gradlew reguardRelease //OS X or Linux
這里的任務命令規則和 build 中的 assemble 一致。
雙擊或右鍵 Run... 下圖中的選中任務,構建以及混淆就會開始:
完成后會提示你混淆后的 apk 生成目錄:
Backup Final APk(V2) to ..\Test\app\build\outputs\apk\release\app-release.apk
<--AndResGuard Done! You can find the output in *\Test\app\build\outputs\apk\release\AndResGuard_app-release
如果不設置 finalApkBackupPath 則會如上面一樣默認覆蓋 assemble 輸出的apk,如果配置則輸出至 finalApkBackupPath 配置的路徑。
例如配置為【finalApkBackupPath = "${project.rootDir}/final.apk"】后的輸出為:
Backup Final APk(V2) to ..\Test\final.apk
<--AndResGuard Done! You can find the output in *\Test\app\build\outputs\apk\release\AndResGuard_app-release
生成的文件
默認會生成4種apk,我們選擇簽名、壓縮、對齊后的 apk 即可,后綴名是*_7zip_aligned_signed.apk
混淆前 apk 解壓后的資源文件:
混淆后 apk 解壓后的資源文件:
2018-7-11