最近在須要對所開發的項目進行了代碼混淆,在android studio中開啓代碼混淆其實仍是挺方便的,不過由於代碼混淆產生的問題很是多,特別是對於一些涉及到反射的第三方庫常常由於名稱的變化致使沒法使用。html
下面介紹android studio中對android項目進行代碼混淆的詳細步驟:java
(1)代碼混淆開啓linux
想要開啓代碼混淆功能,只須要在相應的項目中將 build.gradle 的相應設置開啓便可。android
android{ buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
minifyEnable即爲開啓的開關,而proguard-rules.pro是設置代碼混淆時的相關設置,能夠過濾不代碼混淆的對象。web
(2)代碼混淆規則設置apache
程序中每一個module下面都有對應的proguard-rules.pro文件,設置其規則能夠過濾掉一些類、方法、註解和屬性名的混淆,下面是ProGuard的手冊頁面,詳細的規則能夠在其中瞭解。https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/introduction.htmljson
下面簡單介紹函數
? 忽略任何單個字母oop
* 匹配任何不包含分割符的字符串gradle
** 匹配任意字符串
1)忽略混淆類
-keep
[,modifier,...] class_specification
這個語法能夠保留類或者成員變量的入口不變,舉例以下
-keep public class *{ *; }
上面這個語法能夠匹配任意 public的類以及其成員函數,忽略對其的混淆
-keep class com.example.**{ public static doSomething*(**); }
com.example下的任意類
2) 忽略類的成員
-keepclassmembers [,modifier,...] class_specification
匹配保留類的成員,若是相應的類被保留,則匹配的成員也會被保留
-keepclassmembers class * implements java.io.Serializable { private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); }
3)忽略類和類的成員
-keepclasseswithmembers [,modifier,....] class_specification
只有當全部條件都匹配的時候,它的成員變量和類纔會避免被混淆
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
忽略擁有main函數的類的混淆以及main函數的混淆
4)保留類或者成員的名字
-keepnames class_specification
當條件匹配時,忽略混淆匹配的類名和成員名稱
-keepnames class * implements java.io.Serializable
5) 保留成員變量的名字
-keepclassmembernames class_specification
當條件匹配時,保留其中匹配的成員變量的名字
6)全部條件匹配時,忽略制定類和成員的名字
-keepclasseswithmembernames class_specification
當類名和類的成員都匹配上時,忽略混淆才起效
其中有幾個特別有用的tips, 能夠匹配子類或接口:
-keep class AClass extends PClass -keep class CClass implements IClass -keepclassmemberwithmembernames class com.A.B.C.* { @A.B.C.D <methods> }
具體更詳細的細節,能夠參詳ProGuard的手冊。
(3)常見庫的ProGuard設置
EventBus的ProGuard設置
-keepattributes *Annotation* -keepclassmembers class ** { @org.greenrobot.eventbus.Subscribe <methods>; } -keep enum org.greenrobot.eventbus.ThreadMode { *; } # Only required if you use AsyncExecutor -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { <init>(java.lang.Throwable); }
ButterKnife的ProGuard設置
-keep class butterknife.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewBinder { *; } -keepclasseswithmembernames class * { @butterknife.* <fields>; } -keepclasseswithmembernames class * { @butterknife.* <methods>; }
LeanCloud的ProGuard設置
# proguard.cfg -keepattributes Signature -dontwarn com.jcraft.jzlib.** -keep class com.jcraft.jzlib.** { *;} -dontwarn sun.misc.** -keep class sun.misc.** { *;} -dontwarn com.alibaba.fastjson.** -keep class com.alibaba.fastjson.** { *;} -dontwarn sun.security.** -keep class sun.security.** { *; } -dontwarn com.google.** -keep class com.google.** { *;} -dontwarn com.avos.** -keep class com.avos.** { *;} -keep public class android.net.http.SslError -keep public class android.webkit.WebViewClient -dontwarn android.webkit.WebView -dontwarn android.net.http.SslError -dontwarn android.webkit.WebViewClient -dontwarn android.support.** -dontwarn org.apache.** -keep class org.apache.** { *;} -dontwarn org.jivesoftware.smack.** -keep class org.jivesoftware.smack.** { *;} -dontwarn com.loopj.** -keep class com.loopj.** { *;} -dontwarn com.squareup.okhttp.** -keep class com.squareup.okhttp.** { *;} -keep interface com.squareup.okhttp.** { *; } -dontwarn okio.** -dontwarn org.xbill.** -keep class org.xbill.** { *;} -keepattributes *Annotation*
我本身在開發中使用LeanCloud的LeanMessage自定義消息,由於混淆的緣由老是解析錯誤,加上下面兩句忽略對繼承
com.avos.avoscloud.im.v2.AVIMTypedMessage的混淆便可解決問題,代碼以下
-keep class ** extends com.avos.avoscloud.im.v2.AVIMTypedMessage -keepclassmembers class ** extends com.avos.avoscloud.im.v2.AVIMTypedMessage{ *; }