如何添加混淆呢?
這裏我們使用as作爲開發工具。一般我們會在gradle裏進行如下設置:
buildTypes {
release {
minifyEnabled false //是否壓縮(沒有用的方法以及資源 會進行壓縮)
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//
}
}
使用默認的proguard-android.txt文件的混淆,大致可總結如下三條:
1. Android四大基本組件(在AndroidManifest.xml中註冊的)的類名和重寫的父類方法名不會被混淆。
2. 含有本地native方法的類名以及其中的本地方法名不會被混淆。
3. 第三方Jar包都會被混淆(包括類名和方法名)。
proguard-android.txt,這個東西很吊的樣子,啥都不用該混淆的不該混淆的全搞定。下面我們就具體學習一下里面的混淆規則:
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
#表示混淆時不使用大小寫混合類名。
-dontusemixedcaseclassnames
#表示不跳過library中非public的類。
-dontskipnonpubliclibraryclasses
#表示打印混淆的詳細信息。
-verbose
# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
#表示不進行優化,建議使用此選項,因爲根據proguard-android-optimize.txt中的描述,優化可能會造成一些潛在風險,不能保證在所有版本的Dalvik上都運行正常。
-dontoptimize
#表示不進行預校驗。這個預校驗是作用在Java平臺上的,Android平臺上不需要此項功能,去掉之後還可以加快混淆速度。
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.
#表示對註解參數進行保留。
-keepattributes *Annotation*
#表示不混淆上述聲明的兩個類,這兩個類我們基本也用不上,是接入Google原生的一些服務時使用的。
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
#表示不混淆任何包含native方法的類名以及native方法名。
-keepclasseswithmembernames class * {
native <methods>;
}
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
#表示不混淆任何一個View中的setXxx()和getXxx()方法,因爲屬性動畫需要有相應的setter和getter的方法實現,混淆了就無法工作了。
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick
#表示不混淆Activity中參數是View的方法,因爲有這樣一種用法,在XML中配置android:onClick = "buttionClick"屬性,當用戶點擊該按鈕時就會調用Activity中buttonClick方法,如果被混淆就找不到了。
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
# 表示不混淆枚舉類的values()和 valueOf()方法。
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
#表示不混淆Parcelable實現類中的CREATOR字段,毫無疑問,CREATOR字段是絕對不能改變的,包括大小寫都不能變,不然整個Parecable工作機制都會失敗。
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}
#表示不混淆R文件中所有的靜態字段,R文件是通過字段來記錄每個資源的id的,字段若被混淆,id就找不到了。
-keepclassmembers class **.R$* {
public static <fields>;
}
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
#表示對android:support包下的代碼不警告,因爲support包中有很多代碼都是在高版本中使用的,如果我們的項目指定的版本較低在打包是就會給予警告。不過support包中所有的代碼都在版本兼容性上做足了判斷,因此不用擔心代碼會出問題,直接忽略警告就可以了。
-dontwarn android.support.**
# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep
-keep @android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}
#另外 對於引用第三方包的情況,可以採用下面方式避免打包出錯:
#-libraryjars libs/aaa.jar
#-dontwarn com.xx.yy.**
#-keep class com.xx.yy.** { *;}
下面我們來看一看六個keep相關的關鍵字:
關鍵字 | 描述 |
---|---|
keep | 保留類和類中的成員,防止它們被混淆或移除。 |
keepnames | 保留類和類中的成員,防止它們被混淆,但當成員沒有被引用時會被移除。 |
keepclassmembers | 只保留類中的成員,防止它們被混淆或移除。 |
keepclassmembernames | 只保留類中的成員,防止它們被混淆,但當成員沒有被引用時會被移除。 |
keepclasseswithmembers | 保留類和類中的成員,防止它們被混淆或移除,前提是指名的類中的成員必須存在,如果不存在則還是會混淆。 |
keepclasseswithmembernames | 保留類和類中的成員,防止它們被混淆,但當成員沒有被引用時會被移除,前提是指名的類中的成員必須存在,如果不存在則還是會混淆。 |
還有通配符:
通配符 | 描述 |
---|---|
field | 匹配類中的所有字段 |
method | 匹配類中的所有方法 |
init | 匹配類中的所有構造函數 |
* | 匹配任意長度字符,但不含包名分隔符(.)。比如說我們的完整類名是com.example.test.MyActivity,使用com.,或者com.exmaple.都是無法匹配的,因爲無法匹配包名中的分隔符,正確的匹配方式是com.exmaple..,或者com.exmaple.test.,這些都是可以的。但如果你不寫任何其它內容,只有一個*,那就表示匹配所有的東西。 |
** | 匹配任意長度字符,並且包含包名分隔符(.)。比如proguard-android.txt中使用的-dontwarn android.support.**就可以匹配android.support包下的所有內容,包括任意長度的子包。 |
匹配任意參數類型。比如void set*()就能匹配任意傳入的參數類型, get*()就能匹配任意返回值的類型。 | |
… | 匹配任意長度的任意類型參數。比如void test(…)就能匹配任意void test(String a)或者是void test(int a, String b)這些方法。 |
Android混淆的通用規則
debug調試的apk是沒有混淆的,所以無論你怎麼反編譯,都看到的是源碼,你要檢驗release包是否混淆。
1,系統混淆配置
-dontusemixedcaseclassnames #混淆時不使用大小寫混合類名
-dontskipnonpubliclibraryclasses #不跳過library中的非public的類
-verbose #打印混淆的詳細信息
-dontoptimize #不進行優化,建議使用此選項,
-dontpreverify #不進行預校驗,Android不需要,可加快混淆速度。
-ignorewarnings #忽略警告
#-optimizationpasses 5 #指定代碼的壓縮級別
2,常用的一些混淆配置
-keepattributes Signature #範型
#native方法不混淆
-keepclasseswithmembernames class * {
native <methods>;
}
#v4包不混淆
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
#Gson混淆配置
-keep class sun.misc.Unsafe { *; }
-keep class com.idea.fifaalarmclock.entity.***
-keep class com.google.gson.** { *; }
#JavaBean
-keepclassmembers public class cn.net.duqian.bean.** {
void set*(***);
*** get*();
}
-keep class com.xx.duqian_cloud.JavaScriptInterface { *; }#webview js
#忽略 libiary 混淆
-keep class io.vov.vitamio.** { *; }
#butterknife不混淆
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
第三方框架不混淆,也要看具體情況,不是所有的lib都不能混淆。用了反射的肯定不能混淆。
-keepclassmembers class * {
public <init> (org.json.JSONObject);
}
#okhttp
-dontwarn okhttp3.**
-keep class okhttp3.**{*;}
-keep interface okhttp3.**{*;}
#okio
-dontwarn okio.**
-keep class okio.**{*;}
-keep interface okio.**{*;}
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-dontwarn rx.**
-keep class rx.**{*;}