方案選擇:
1.微信混淆方案(AndResGuard)
2.美團(tuán)混淆方案
區(qū)別:
微信的方案是通過(guò)修改aapt在處理資源文件相關(guān)的源碼達(dá)到資源文件的替換骆膝;而美團(tuán)主要通過(guò)直接修改resources.arsc文件達(dá)到資源文件混淆的目的计贰。微信從aapt的原理上著手畴蹭,而美團(tuán)只是在已有的方案上優(yōu)化惕耕,相比之下琅捏,微信的混淆更徹底驱敲。
什么是AndResGuard
??AndResGuard是一個(gè)縮小APK大小的工具热凹,它的原理類(lèi)似Java Proguard鹿霸,但是只針對(duì)資源排吴。它會(huì)將原本冗長(zhǎng)的資源路徑變短,例如將res/drawable/wechat變?yōu)閞/d/a懦鼠。
在以往的開(kāi)發(fā)中钻哩,我們通常只混淆了代碼,資源文件卻暴露在他人面前肛冶,res文件夾下所有文件名的可讀性過(guò)強(qiáng)街氢。
微信的開(kāi)源庫(kù)AndResGuard正好解決這種問(wèn)題,對(duì)資源進(jìn)行混淆睦袖,保護(hù)res資源文件的可讀性珊肃,同時(shí),可以減少APP的大小
AndResGuard的配置
- 項(xiàng)目根目錄下build.gradle中,添加插件的依賴(lài):
dependencies {
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.10'
}
- app模塊中build.gradle中近范,添加相關(guān)配置
apply plugin: 'AndResGuard'
andResGuard {
// mappingFile = file("./resource_mapping.txt")
mappingFile = null
use7zip = false
useSign = true
// It will keep the origin path of your resources when it's true
keepRoot = false
// If set, name column in arsc those need to proguard will be kept to this value
fixedResName = "arg"
// It will merge the duplicated resources, but don't rely on this feature too much.
// it's always better to remove duplicated resource from repo
mergeDuplicatedRes = true
whiteList = [
// your icon
"R.drawable.ic_launcher*",
"R.anim.umeng*",
"R.string.umeng*",
]
compressFilePattern = [
"*.png",
"*.jpg",
"*.jpeg",
"*.gif",
"*.webp",
]
sevenzip {
artifact = 'com.tencent.mm:SevenZip:1.2.20'
//path = "/usr/local/bin/7za"
}
/**
* Optional: if finalApkBackupPath is null, AndResGuard will overwrite final apk
* to the path which assemble[Task] write to
**/
// finalApkBackupPath = "${project.rootDir}/final.apk"
/**
* Optional: Specifies the name of the message digest algorithm to user when digesting the entries of JAR file
* Only works in V1signing, default value is "SHA-1"
**/
// digestalg = "SHA-256"
}
其中whiteList(白名單)中指定不需要進(jìn)行混淆的資源路徑規(guī)則嘶摊,主要是針對(duì)第三方SDK,因?yàn)橛行㏒DK的代碼中通過(guò)getIdentifier()的方式引用到對(duì)應(yīng)的資源文件评矩,如果對(duì)其進(jìn)行混淆叶堆,會(huì)導(dǎo)致找不到對(duì)應(yīng)資源文件,出現(xiàn)crash斥杜。
androId尋找資源方式:
resources.arsc結(jié)構(gòu):
通過(guò)包名(package name)虱颗,類(lèi)型(type,如dimen,drawable,color,string等),資源名(name)在表resources.arsc中查找對(duì)應(yīng)資源的Id.
然后通過(guò)getResources().getDrawable(resourceId)或者getResources().getDimensionPixelSize(resourceId)等方法拿到對(duì)應(yīng)的資源.
而一旦進(jìn)行資源混淆后蔗喂,資源名發(fā)生變化忘渔,會(huì)導(dǎo)致找不到資源id。