Android Studio 代碼混淆

在Android studio 進行代碼混淆配置。java

proguard 配置android

-keepclasseswithmembers 指定的類和類成員被保留,假如指定的類成員存在的話。算法

-dontwarn 缺省proguard 會檢查每個引用是否正確,可是第三方庫裏面每每有些不會用到的類,沒有正確引用。若是不配置的話,系統就會報錯。數據庫

-keep 指定的類和類成員被保留做爲 入口 。app

-keepclassmembers 指定的類成員被保留。框架


proguard 問題和風險ide

代碼混淆後雖然有混淆優化的好處,可是它每每也會帶來以下的幾點問題測試

混淆錯誤,用到第三方庫的時候,必須告訴 proguard 不要檢查,不然proguard 會報錯。gradle

運行錯誤,當code 不能混淆的時候,咱們必需要正確配置,不然程序會運行出錯,這種狀況問題最多。優化

調試苦難,出錯了,錯誤堆棧是混淆後的代碼 ,本身也看不懂。


不能混淆的代碼

下面這樣代碼混淆的時候要注意保留。

Android系統組件,系統組件有固定的方法被系統調用。

被Android Resource 文件引用到的。名字已經固定,也不能混淆,好比自定義的View 

Android Parcelable ,須要使用android 序列化的。

Java序列化方法,系統序列化須要固定的方法。

枚舉 ,系統須要處理枚舉的固定方法

本地方法,不能修改本地方法名

annotations 註釋

數據庫驅動

有些resource 文件

用到反射的地方

其餘Anroid 官方建議 不混淆的,如

android.app.backup.BackupAgentHelper

android.preference.Preference

com.android.vending.licensing.ILicensingService


混淆配置

proguard 參數

-include {filename}    從給定的文件中讀取配置參數 

-basedirectory {directoryname}    指定基礎目錄爲之後相對的檔案名稱 

-injars {class_path}    指定要處理的應用程序jar,war,ear和目錄 

-outjars {class_path}    指定處理完後要輸出的jar,war,ear和目錄的名稱 

-libraryjars {classpath}    指定要處理的應用程序jar,war,ear和目錄所須要的程序庫文件 

-dontskipnonpubliclibraryclasses    指定不去忽略非公共的庫類。 

-dontskipnonpubliclibraryclassmembers    指定不去忽略包可見的庫類的成員。 

保留選項 

-keep {Modifier} {class_specification}    保護指定的類文件和類的成員 

-keepclassmembers {modifier} {class_specification}    保護指定類的成員,若是此類受到保護他們會保護的更好

-keepclasseswithmembers {class_specification}    保護指定的類和類的成員,但條件是全部指定的類和類成員是要存在。 

-keepnames {class_specification}    保護指定的類和類的成員的名稱(若是他們不會壓縮步驟中刪除) 

-keepclassmembernames {class_specification}    保護指定的類的成員的名稱(若是他們不會壓縮步驟中刪除) 

-keepclasseswithmembernames {class_specification}    保護指定的類和類的成員的名稱,若是全部指定的類成員出席(在壓縮步驟以後) 

-printseeds {filename}    列出類和類的成員-keep選項的清單,標準輸出到給定的文件 

壓縮 

-dontshrink    不壓縮輸入的類文件 

-printusage {filename} 

-whyareyoukeeping {class_specification}    

優化 

-dontoptimize    不優化輸入的類文件 

-assumenosideeffects {class_specification}    優化時假設指定的方法,沒有任何反作用 

-allowaccessmodification    優化時容許訪問並修改有修飾符的類和類的成員 

混淆 

-dontobfuscate    不混淆輸入的類文件 

-printmapping {filename} 

-applymapping {filename}    重用映射增長混淆 

-obfuscationdictionary {filename}    使用給定文件中的關鍵字做爲要混淆方法的名稱 

-overloadaggressively    混淆時應用侵入式重載 

-useuniqueclassmembernames    肯定統一的混淆類的成員名稱來增長混淆 

-flattenpackagehierarchy {package_name}    從新包裝全部重命名的包並放在給定的單一包中 

-repackageclass {package_name}    從新包裝全部重命名的類文件中放在給定的單一包中 

-dontusemixedcaseclassnames    混淆時不會產生形形色色的類名 

-keepattributes {attribute_name,...}    保護給定的可選屬性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses. 

-renamesourcefileattribute {string}    設置源文件中給定的字符串常量



下面是一個混淆模板吧。註釋很清楚。

#指定代碼的壓縮級別
-optimizationpasses 5
#包明不混合大小寫
-dontusemixedcaseclassnames
#不去忽略非公共的庫類
-dontskipnonpubliclibraryclasses
 #優化  不優化輸入的類文件
-dontoptimize
 #預校驗
-dontpreverify
 #混淆時是否記錄日誌
-verbose
 # 混淆時所採用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#保護註解
-keepattributes *Annotation*
# 保持哪些類不被混淆
-keep public class * extends android.app.Fragment
-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.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 com.android.vending.licensing.ILicensingService
#若是有引用v4包能夠添加下面這行
-keep public class * extends android.support.v4.app.Fragment
#忽略警告
-ignorewarning
#####################記錄生成的日誌數據,gradle build時在本項目根目錄輸出################
#apk 包內全部 class 的內部結構
-dump class_files.txt
#未混淆的類和成員
-printseeds seeds.txt
#列出從 apk 中刪除的代碼
-printusage unused.txt
#混淆先後的映射
-printmapping mapping.txt
#####################記錄生成的日誌數據,gradle build時 在本項目根目錄輸出-end################
################<span></span>混淆保護本身項目的部分代碼以及引用的第三方jar包library#########################
#-libraryjars libs/umeng-analytics-v5.2.4.jar
#-libraryjars libs/alipaysd<span></span>k.jar
#<span></span>-libraryjars libs/alipaysecsdk.jar
#-libraryjars libs/alipayutdid.jar
#-libraryjars libs/wup-1.0.0-SNAPSHOT.jar
#-libraryjars libs/weibosdkcore.jar
#三星應用市場須要添加:sdk-v1.0.0.jar,look-v1.0.1.jar
#-libraryjars libs/sdk-v1.0.0.jar
#-libraryjars libs/look-v1.0.1.jar
#我是以libaray的形式引用了一個圖片加載框架,若是不想混淆 keep 掉
-keep class com.nostra13.universalimageloader.** { *; }
#友盟
-keep class com.umeng.**{*;}
#支付寶
-keep class com.alipay.android.app.IAliPay{*;}
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.lib.ResourceMap{*;}
#信鴿推送
-keep class com.tencent.android.tpush.**  {* ;}
-keep class com.tencent.mid.**  {* ;}
#本身項目特殊處理代碼
#忽略警告
-dontwarn com.veidy.mobile.common.**
#保留一個完整的包
-keep class com.veidy.mobile.common.** {
    *;
 }
-keep class  com.veidy.activity.login.WebLoginActivity{*;}
-keep class  com.veidy.activity.UserInfoFragment{*;}
-keep class  com.veidy.activity.HomeFragmentActivity{*;}
-keep class  com.veidy.activity.CityActivity{*;}
-keep class  com.veidy.activity.ClinikActivity{*;}
#若是引用了v4或者v7包
-dontwarn android.support.**
############<span></span>混淆保護本身項目的部分代碼以及引用的第三方jar包library-end##################
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}
#保持 native 方法不被混淆
-keepclasseswithmembernames class * {
    native <methods>;
}
#保持自定義控件類不被混淆
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}
#保持自定義控件類不被混淆
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
#保持自定義控件類不被混淆
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}
#保持 Parcelable 不被混淆
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
#保持 Serializable 不被混淆
-keepnames class * implements java.io.Serializable
#保持 Serializable 不被混淆而且enum 類也不被混淆
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    !private <fields><span></span>;
    !private <methods>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
#保持枚舉 enum 類不被混淆 若是混淆報錯,建議直接使用上面的 -keepclassmembers class * implements java.io.Serializable便可
#-keepclassmembers enum * {
#  public static **[] values();
#  public static ** valueOf(java.lang.String);
#}
-keepclassmembers class * {
    public void *ButtonClicked(android.view.View);
}
#不混淆資源類
-keepclassmembers class **.R$* {
    public static <fields>;
}
#避免混淆泛型 若是混淆報錯建議關掉
#–keepattributes Signature
#移除log 測試了下沒有用仍是建議本身定義一個開關控制是否輸出日誌
#-assumenosideeffects class android.util.Log {
#    public static boolean isLoggable(java.lang.String, int);
#    public static int v(...);
#    public static int i(...);
#    public static int w(...);
#    public static int d(...);
#    public static int e(...);
#}
相關文章
相關標籤/搜索