1. 程式人生 > >我的Android混淆(Proguard檔案)是怎麼寫的

我的Android混淆(Proguard檔案)是怎麼寫的

去過幾家公司之後發現原來的老專案裡面的的ProGuard寫的很亂,可能因為Proguard檔案要靠手寫,所以有時候感覺很難,但是找到規律之後你會發現也挺簡單的。感覺難是因為,不熟悉它的一些關鍵字,我在這裡列出了常用的關鍵字,以及標註了些人能看懂的含義,來分享一下我這幾年總結的Proguard的檔案,一直想寫一篇如何在Proguard中排查錯誤的文章,一直沒空。其實要想看明白,自己寫的Demo測試一下就好了,藉助於反編譯工具看下到底什麼被混淆了,工具看這。我下面的關鍵部分寫了詳細的註釋github,常用的也就這麼多了,其餘的可以根據命令列進行除錯,然後逐個新增。一般現在Proguard配合Gradle一塊用

Gradle 入門–只此一篇

#-ignorewarnings                     # 忽略警告,避免打包時某些警告出現
-optimizationpasses 5               # 指定程式碼的壓縮級別
-dontusemixedcaseclassnames         # 是否使用大小寫混合 混淆時不會產生形形色色的類名
-dontskipnonpubliclibraryclasses    # 是否混淆第三方jar
-dontpreverify                      # 混淆時是否做預校驗
-verbose                            # 混淆時是否記錄日誌
-dontoptimize # 不優化輸入的類檔案 -keepattributes *Annotation*, SourceFile, InnerClasses, LineNumberTable, Signature, EnclosingMethod -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #優化 混淆時採用的演算法 -keep public class * extends android.app.Activity # 未指定成員,僅僅保持類名不被混淆
-keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.app.View -keep public class * extends android.app.IntentService -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep public class * extends android.app.backup.BackupAgentHelper -keep public class * extends android.preference.Preference -keep public class * extends android.hardware.display.DisplayManager -keep public class * extends android.os.UserManager -keep public class com.android.vending.licensing.ILicensingService -keep public class * extends android.app.Fragment -keep public class * extends android.support.v4.widget -keep public class * extends android.support.v4.** # *匹配任意字元不包括. **匹配任意字元 -keep interface android.support.v4.app.** { *; } #{ *;} 表示一個介面中的所有的東西都不被混淆 # 下面這行表示保持這個包下面的所有的類裡面的所有內容都不混淆 -keep class android.support.v4.** { *; } -keep class android.os.**{*;} -keep class android.support.v8.renderscript.** { *; } -keep class **.R$* { *; } -keep class **.R{ *; } #實現了android.os.Parcelable介面類的任何類,以及其內部定義的Creator內部類型別的public final靜態成員變數,都不能被混淆和刪除 -keep class * implements android.os.Parcelable { # 保持Parcelable不被混淆 public static final android.os.Parcelable$Creator *; } -keepclasseswithmembernames class * { # 保持 native 方法不被混淆 native <methods>; } -keepclasseswithmembers class * { # 保持自定義控制元件類不被混淆 public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembers class * { # 保持自定義控制元件類不被混淆 public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int, int); } -keepclassmembers class * extends android.app.Activity { #保持類成員 public void *(android.view.View); } -keepclassmembers class * extends android.content.Context { public void *(android.view.View); public void *(android.view.MenuItem); } -keepclassmembers enum * { # 保持列舉 enum 類不被混淆 public static **[] values(); public static ** valueOf(java.lang.String); } # Explicitly preserve all serialization members. The Serializable interface # is only a marker interface, so it wouldn't save them. -keepnames class * implements java.io.Serializable -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; 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(); } #-libraryjars libs/jar包名字.jar #預設proguard 會檢查每一個引用是否正確,但是第三方庫裡面往往有些不會用到的類,沒有正確引用。如果不配置的話,系統就會報錯。 -dontwarn android.support.v4.** -dontwarn android.os.** #編譯時關掉Log的列印, #-assumenosideeffects class android.util.Log { #如果是自定義Log類,修改下面的包名 # public static *** d(...); # public static *** e(...); # public static *** i(...); # public static *** v(...); # public static *** println(...); # public static *** w(...); # public static *** wtf(...); #} ##############################--------以上是Android基本配置----------############################## # 實體類不混淆(自己專案實體類不被混淆,因為Gson中用到了反射) #-keep class me.febsky.entity.** { *; } ### -----這是個列子---- ### #這個類裡面的所有的成員變數和方法都不混淆 -keep class me.febsky.testprogard.MainActivity { *; } #這個類裡面的內部類的所有的成員變數和方法都不混淆 -keep class me.febsky.testprogard.MainActivity$* { *; } #這個類裡面的所有public的內部類的所有的成員變數和方法都不混淆 -keep public class me.febsky.testprogard.MainActivity$* { *; } #這個類裡面的內部類的類名不備混淆,方法和變數還是混淆的 -keep class me.febsky.testprogard.MainActivity$* #保持一個類的類名不被混淆,裡面的方法和成員變數名還是被混淆的 -keep public class me.febsky.testprogard.MyOutClass ### -----這是個列子---- ### ## for sharedSDK -keep class android.net.http.SslError -keep class android.webkit.**{*;} -keep class cn.sharesdk.**{*;} -keep class com.sina.**{*;} -keep class m.framework.**{*;} #butter knife -keep class butterknife.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewBinder { *; } -keepclasseswithmembernames class * { @butterknife.* <fields>; } -keepclasseswithmembernames class * { @butterknife.* <methods>; }