Android Progurad 代碼混淆
ref:
ProGuard基礎文法和打包配置.md
https://github.com/D-clock/Doc/blob/master/Android/Gradle/3_ProGuard%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95%E5%92%8C%E6%89%93%E5%8C%85%E9%85%8D%E7%BD%AE.md
AndroidStudio下ProGuard混淆打包
https://github.com/D-clock/Doc/blob/master/Android/Gradle/4_AndroidStudio%E4%B8%8BProGuard%E6%B7%B7%E6%B7%86%E6%89%93%E5%8C%85.md
proguard-rules.pro 模闆
https://github.com/AnyLifeZLB/AndroidAppFrameWork/blob/master/main/proguard-rules.pro
Proguard官方使用手冊:
https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/usage.html
代碼壓縮通過 ProGuard 提供,ProGuard 會檢測和移除封裝應用中未使用的類、字段、方法和屬性,包括自帶代碼庫中的未使用項(這使其成為以變通方式解決 64k 引用限制的有用工具)。ProGuard 還可優化位元組碼,移除未使用的代碼指令,以及用短名稱混淆其餘的類、字段和方法。混淆過的代碼可令您的 APK 難以被逆向工程,這在應用使用許可驗證等安全敏感性功能時特别有用。
要啟用資源壓縮,請在
build.gradle
檔案中将
shrinkResources
屬性設定為
true
(在用于代碼壓縮的
minifyEnabled
旁邊)。例如:
android {
...
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
如果您尚未使用代碼壓縮用途的
minifyEnabled
建構應用,請先嘗試使用它,然後再啟用
shrinkResources
,因為您可能需要編輯
proguard-rules.pro
檔案以保留動态建立或調用的類或方法,然後再開始移除資源。
8. 混淆技巧
混淆能讓反編譯的代碼可讀性變的很差,而且還能顯著的減少APK包的大小。
1). 第一個技巧
相信很多朋友對混淆都覺得麻煩,甚至說,非常亂。因為添加混淆規則需要查詢官方說明文檔,甚至有的官方文檔還沒說明。當你引用了太多庫後,添加混淆規則将使一場噩夢。
這裡介紹一個技巧,不用查官方文檔,不用逐個庫考慮添加規則。
首先,除了預設的混淆配置(android-sdk/tools/proguard/proguard-android.txt), 自己的代碼肯定是要自己配置的:
## 位于module下的proguard-rules.pro
#####################################
######### 主程式不能混淆的代碼 #########
#####################################
-dontwarn xxx.model.**
-keep class xxx.model.** { *; }
## 等等,自己的代碼自己清楚
#####################################
########### 不優化泛型和反射 ##########
#####################################
-keepattributes Signature
接下來是麻煩的第三方庫,一般來說,如果是極光推的話,它的包名是cn.jpush, 添加如下代碼即可:
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
其他的第三庫也是如此,一個一個添加,太累!其實可以用第三方反編譯工具(比如jadx:https://github.com/skylot/jadx ),打開apk後,一眼就能看到引用的所有第三方庫的包名,把所有不想混淆或者不确定能不能混淆的,直接都添加又有何不可:
#####################################
######### 第三方庫或者jar包 ###########
#####################################
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
-dontwarn com.squareup.**
-keep class com.squareup.** { *; }
-dontwarn com.octo.**
-keep class com.octo.** { *; }
-dontwarn de.**
-keep class de.** { *; }
-dontwarn javax.**
-keep class javax.** { *; }
-dontwarn org.**
-keep class org.** { *; }
-dontwarn u.aly.**
-keep class u.aly.** { *; }
-dontwarn uk.**
-keep class uk.** { *; }
-dontwarn com.baidu.**
-keep class com.baidu.** { *; }
-dontwarn com.facebook.**
-keep class com.facebook.** { *; }
-dontwarn com.google.**
-keep class com.google.** { *; }
## ... ...
2). 第二個技巧
一般release版本混淆之後,像友盟這樣的統計系統如果有崩潰異常,會記錄如下:
java.lang.NullPointerException: java.lang.NullPointerException
at com.xxx.TabMessageFragment$7.run(Unknown Source)
這個Unknown Source是很要命的,排除錯誤無法定位到具體行了,大大降低調試效率。
當然,友盟支援上傳Mapping檔案,可幫助定位,mapping檔案的位置在:
project > module
> build > outputs > {flavor name} > {build type} > mapping.txt
如果版本一多,mapping.txt每次都要重新生成,還要上傳,終歸還是麻煩。
其實,在proguard-rules.pro中添加如下代碼即可:
-keepattributes SourceFile,LineNumberTable
當然apk包會大那麼一點點(我這裡6M的包,大個200k吧),但是再也不用mapping.txt也能定位到行了,為了這種解脫,這個代價我個人覺得是值的,而且超值!