標籤:ini 第三方庫 tty 控制項 keyword reference map 怎麼 添加
一、前言
今天要打包新產品,突然忘了混淆的參數是怎麼寫的了,雖然之前也混淆過,可是具體配置的參數代碼有些記不起來了,因此決定花點時間寫篇部落格記錄一下,方便以後尋找和自己的記憶。
二、Android Studio 代碼混淆基本配置
在工程目錄下,找到 proguard-rules.pro 檔案,它就是你要進行編寫混淆配置的檔案,在這個檔案中編寫混淆規則
當然,在這之前,還需要在你 module 的 build.gradle 檔案中引用該混淆檔案:
上面中的 proguard-android.txt 檔案,這是系統預設的混淆檔案,具體在../sdk/tools/proguard/ 目錄下,其中包含了 android 最基本的混淆,一般不需要改動,我們需要配置的是項目中 app 下的 proguard-rules.pro 檔案
三、混淆規則
1.基本規則
兩個常用的混淆命令,注意一顆星表示只是保持該包下的類名,而子包下的類名還是會被混淆;兩顆星表示把本包和所含子包下的類名都保持;
-keep class cn.hadcn.test.**-keep class cn.hadcn.test.*
用以上方法保持類後,你會發現類名雖然未混淆,但裡面的具體方法和變數命名還是變了,這時如果既想保持類名,又想保持裡面的內容不被混淆,我們就需要以下方法了
-keep class com.example.bean.** { *; }
在此基礎上,我們也可以使用Java的基本規則來保護特定類不被混淆,比如我們可以用extend,implement等這些Java規則。如下例子就避免所有繼承Activity的類被混淆
# 保留我們使用的四大組件,自訂的Application等等這些類不被混淆# 因為這些子類都有可能被外部調用-keep public class * extends android.app.Activity-keep public class * extends android.app.Appliction-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 * extends android.view.View-keep public class com.android.vending.licensing.ILicensingService
2.什麼時候不被混淆
一般以下情況都會不混淆:
1.使用了自訂控制項那麼要保證它們不參與混淆
2.使用了枚舉要保證枚舉不被混淆
3.對第三方庫中的類不進行混淆
4.運用了反射的類也不進行混淆
5.使用了 Gson 之類的工具要使 JavaBean 類即實體類不被混淆
6.在引用第三方庫的時候,一般會標明庫的混淆規則的,建議在使用的時候就把混淆規則添加上去,免得到最後才去找
7.有用到 WebView 的 JS 調用也需要保證寫的介面方法不混淆,原因和第一條一樣
8.Parcelable 的子類和 Creator 靜態成員變數不混淆,否則會產生 Android.os.BadParcelableException 異常
三、基本的混淆模板
最後提供一份基本的混淆模板,當然第三方庫,或者上面提到的地方,根據自己的實際需求進行混淆
############################################### 對於一些基本指令的添加############################################### 代碼混淆壓縮比,在0~7之間,預設為5,一般不做修改-optimizationpasses 5# 混合時不使用大小寫混合,混合後的類名為小寫-dontusemixedcaseclassnames# 指定不去忽略非公用庫的類-dontskipnonpubliclibraryclasses# 這句話能夠使我們的項目混淆後產生對應檔# 包含有類名->混淆後類名的映射關係-verbose# 指定不去忽略非公用庫的類成員-dontskipnonpubliclibraryclassmembers# 不做預校正,preverify是proguard的四個步驟之一,Android不需要preverify,去掉這一步能夠加快混淆速度。-dontpreverify# 保留Annotation不混淆-keepattributes *Annotation*,InnerClasses# 避免混淆泛型-keepattributes Signature# 拋出異常時保留程式碼號-keepattributes SourceFile,LineNumberTable# 指定混淆是採用的演算法,後面的參數是一個過濾器# 這個過濾器是Google推薦的演算法,一般不做更改-optimizations !code/simplification/cast,!field/*,!class/merging/*############################################### Android開發中一些需要保留的公用部分############################################### 保留我們使用的四大組件,自訂的Application等等這些類不被混淆# 因為這些子類都有可能被外部調用-keep public class * extends android.app.Activity-keep public class * extends android.app.Appliction-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 * extends android.view.View-keep public class com.android.vending.licensing.ILicensingService# 保留support下的所有類及其內部類-keep class android.support.** {*;}# 保留繼承的-keep public class * extends android.support.v4.**-keep public class * extends android.support.v7.**-keep public class * extends android.support.annotation.**# 保留R下面的資源-keep class **.R$* {*;}# 保留本地native方法不被混淆-keepclasseswithmembernames class * { native <methods>;}# 保留在Activity中的方法參數是view的方法,# 這樣以來我們在layout中寫的onClick就不會被影響-keepclassmembers class * extends android.app.Activity{ public void *(android.view.View);}# 保留枚舉類不被混淆-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String);}# 保留我們自訂控制項(繼承自View)不被混淆-keep public class * extends android.view.View{ *** get*(); void set*(***); public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int);}# 保留Parcelable序列化類別不被混淆-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *;}# 保留Serializable序列化的類不被混淆-keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; !static !transient <fields>; !private <fields>; !private <methods>; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve();}# 對於帶有回呼函數的onXXEvent、**On*Listener的,不能被混淆-keepclassmembers class * { void *(**On*Event); void *(**On*Listener);}# webView處理,項目中沒有使用到webView忽略即可-keepclassmembers class fqcn.of.javascript.interface.for.webview { public *;}-keepclassmembers class * extends android.webkit.webViewClient { public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap); public boolean *(android.webkit.WebView, java.lang.String);}-keepclassmembers class * extends android.webkit.webViewClient { public void *(android.webkit.webView, jav.lang.String);}
Android Studio 代碼混淆(你真的會混淆嗎)