常用混淆規(guī)則
#不混淆某個(gè)類
-keep public class com.webi.demo.TestClass {*;}
#不混淆某個(gè)包的所有類
-keep class com.webi.demo.** {*;}
#不混淆某個(gè)類的子類
-keep public class * extends com.webi.demo.TestClass {*;}
#不混淆某個(gè)接口的實(shí)現(xiàn)
-keep class * implements com.webi.demo.TestInterface {*;}
#不混淆某個(gè)類的特定方法
-keepclassmembers class com.webi.demo.TestClass{
public void test(java.lang.String);
}
#不混淆某個(gè)類的內(nèi)部類
-keep class com.webi.demo.TestClass$* {*;}
什么是混淆
把代碼中原來有具體含義的包名、類名、變量名、方法名等名稱全部替換成無意義的字母a/b/c…
為什么要混淆
由于Android是基于Java語言的,而Java屬于高層抽象語言,易于反編譯,其編譯后的程序包中包含了大量的源代碼變量、方法名、數(shù)據(jù)結(jié)構(gòu)等近乎源碼的信息,等同于將源碼拱手送人。因此為了保護(hù)自己的勞動(dòng)成果以及項(xiàng)目私密問題,我們需要給自己的項(xiàng)目加上混淆。
混淆會(huì)出現(xiàn)什么問題
不難理解,由于混淆后,各種變量、方法、類等信息變成了無意義的字母a/b/c,所以會(huì)出現(xiàn)ClassNotFoundException的錯(cuò)誤,為了避免出現(xiàn)這樣的錯(cuò)誤,我們需要添加一系列的規(guī)則,來標(biāo)注出我們不希望混淆的地方。
常見的保持相關(guān)元素不參與混淆的幾種指令
| 命令 | 作用 |
|---|---|
| -keep | 防止類和成員被移除和被重命名 |
| -keepclassmembers | 防止成員被移除和被重命名 |
| -keepnames | 防止類和成員被重命名 |
| -keepclassmembernames | 防止成員被重命名 |
| -keepclasseswithmembers | 防止擁有該成員的類和成員被移除或重命名 |
| -keepclasseswithmembernames | 防止擁有該成員的類和成員被重命名 |
沒有規(guī)則

默認(rèn)值,如果你沒有指定任何類型的keep指令,那么它會(huì)壓縮(刪除未使用的代碼)并對(duì)類和類成員進(jìn)行模糊處理(即重命名)
-keep

-keep為不壓縮、不混淆。
-keepclassmembers

使用這個(gè)規(guī)則,如果一個(gè)類未被使用,則會(huì)被刪除。如果一個(gè)類被使用了,則會(huì)重命名這個(gè)的類的名字,它所有的成員都還在,并且還是原來的名字。
-keepnames

允許類和成員壓縮,但不能混淆。也就是說,任何未使用的代碼都將被刪除,但保留下來的代碼將保留其原始名稱。
-keepclassmembernames

刪除未使用的類和成員變量,混淆類名,保留成員的原始名稱。
-keepclasseswithmembers
與-keep相同,不同之處在于它僅適用于具有類規(guī)范中所有成員的類。
-keepclasseswithmembernames
此規(guī)則與-keepnames相同。不同的是,它僅適用于具有類規(guī)范中所有成員的類。
更多詳細(xì)的請(qǐng)到官網(wǎng)
保持元素不參與混淆的規(guī)則
[保持命令] [類] {
[成員]
}
[類]表示類相關(guān)的限定條件,它將最終定位到某些符合該限定條件的類。它的內(nèi)容可以使用:
- 具體的類
- 訪問修飾符(public、protected、private)
- 通配符*,匹配任意長度字符,但不含包名分隔符.
- 通配符**,匹配任意長度字符,并且包含包名分隔符.
- extends,即可以指定類的基類
- implement,匹配實(shí)現(xiàn)了某接口的類
- $,內(nèi)部類
[成員]代表類成員相關(guān)的限定條件,它將最終定位到某些符合該限定條件的類成員。它的內(nèi)容可以使用:
- <init>匹配所有構(gòu)造器
- <methods>匹配所有方法
- 通配符*,匹配任意長度字符,但不含包名分隔符.
- 通配符**,匹配任意長度字符,并且包含包名分隔符.
- 通配符***,匹配任意參數(shù)類型
- ...,匹配任意長度的任意類型參數(shù)。比如void test(...)就能匹配任意void test(String a)或者是void test(int a, int b)這些方法
- 訪問修飾符(public、protected、private)
例如,需要將com.demo.test包下所有繼承Activity的public類及其構(gòu)造函數(shù)都保持住,可以這么寫:
-keep public class com.webi.mixdemo.*** extends Android.app.Avtivty{
<init>
}