讓你徹底會安卓Proguard混淆

代碼混淆(Obfuscated code)亦稱花指令振定,是將計算機程序的代碼,轉(zhuǎn)換成一種功能上等價琴许,但是難于閱讀和理解的形式的行為趣钱。

Proguard是什么

  • Proguard是一個集文件壓縮,優(yōu)化,混淆和校驗等功能的工具
  • 它檢測并刪除無用的類,變量,方法和屬性
  • 它優(yōu)化字節(jié)碼并刪除無用的指令.
  • 它通過將類名,變量名和方法名重命名為無意義的名稱實現(xiàn)混淆效果.
  • 最后它還校驗處理后的代碼

混淆的常見配置

  • Proguard關(guān)鍵字
Proguard關(guān)鍵字 描述
dontwarn dontwarn是一個和keep可以說是形影不離,尤其是處理引入的library時.
keep 保留類和類中的成員,防止被混淆或移除
keepnames 保留類和類中的成員星岗,防止被混淆填大,成員沒有被引用會被移除
keepclassmembers 只保留類中的成員,防止被混淆或移除
keepclassmembernames 只保留類中的成員俏橘,防止被混淆允华,成員沒有引用會被移除
keepclasseswithmembers 保留類和類中的成員,防止被混淆或移除敷矫,保留指明的成員
keepclasseswithmembernames 保留類和類中的成員例获,防止被混淆汉额,保留指明的成員曹仗,成員沒有引用會被移除
  • Proguard通配符
Proguard通配符 描述
<field> 匹配類中的所有字段
<method> 匹配類中所有的方法
<init> 匹配類中所有的構(gòu)造函數(shù)
* 匹配任意長度字符,不包含包名分隔符(.)
** 匹配任意長度字符蠕搜,包含包名分隔符(.)
*** 匹配任意參數(shù)類型
... ...
  • 例如:

(1) 保留某個包下面的類以及子包

-keep class de.greenrobot.dao.**

(2) 保留所有類中的public帶View參數(shù)方法
處理xml中些onClick方法

-keepclassmembers class * extends android.app.Activity{
  public void *(android.view.View);
}

開啟混淆

通常我們需要找到項目路徑下app目錄下的build.gradle文件,找到minifyEnabled這個配置,然后設(shè)置為true即可.

release {
     minifyEnabled true//是否啟動混淆 ture:打開   false:關(guān)閉
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}

基本混淆

#############################################
#
# 對于一些基本指令的添加
#
#############################################
# 代碼混淆壓縮比怎茫,在0~7之間,默認為5妓灌,一般不做修改
-optimizationpasses 5

# 混合時不使用大小寫混合轨蛤,混合后的類名為小寫
-dontusemixedcaseclassnames
# 指定不去忽略非公共庫的類
-dontskipnonpubliclibraryclasses
# 這句話能夠使我們的項目混淆后產(chǎn)生映射文件
# 包含有類名->混淆后類名的映射關(guān)系
-verbose
# 指定不去忽略非公共庫的類成員
-dontskipnonpubliclibraryclassmembers
# 不做預(yù)校驗,preverify是proguard的四個步驟之一虫埂,Android不需要preverify祥山,去掉這一步能夠加快混淆速度。
-dontpreverify
# 保留Annotation不混淆
-keepattributes *Annotation*,InnerClasses
# 避免混淆泛型
-keepattributes Signature
# 拋出異常時保留代碼行號
-keepattributes SourceFile,LineNumberTable
# 指定混淆是采用的算法掉伏,后面的參數(shù)是一個過濾器
# 這個過濾器是谷歌推薦的算法缝呕,一般不做更改
-optimizations !code/simplification/cast,!field/*,!class/merging/*
#############################################
#
# Android開發(fā)中一些需要保留的公共部分
#
#############################################
# 保留我們使用的四大組件澳窑,自定義的Application等等這些類不被混淆
# 因為這些子類都有可能被外部調(diào)用
-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

# 保留R下面的資源
-keep class **.R$* {*;}

# 保留本地native方法不被混淆
-keepclasseswithmembernames class * {
    native <methods>;
}

# 保留在Activity中的方法參數(shù)是view的方法,
-keepclassmembers class * extends android.app.Activity{
    public void *(android.view.View);
}

# 保留枚舉類不被混淆
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# support
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**

# androidx的混淆
-keep class com.google.android.material.** {*;}
-keep class androidx.** {*;}
-keep public class * extends androidx.**
-keep interface androidx.** {*;}
-dontwarn com.google.android.material.**
-dontnote com.google.android.material.**
-dontwarn androidx.**

# 保留我們自定義控件(繼承自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();
}

# 對于帶有回調(diào)函數(shù)的onXXEvent供常、**On*Listener的摊聋,不能被混淆
-keepclassmembers class * {
    void *(**On*Event);
    void *(**On*Listener);
}

# webview 還要注意native接口
-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);
}

# keep annotated by NotProguard
-keep @top.andnux.proguard.annotation.Keep class * {*;}
-keep class * {
    @top.andnux.proguard.annotation.Keep <fields>;
}
-keepclassmembers class * {
    @top.andnux.proguard.annotation.Keep <methods>;
}

# 刪除代碼中Log相關(guān)的代碼
-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(...);
}

第三方混淆

#############################################
#
# 第三方混淆規(guī)則
#
#############################################

# 百度地圖混淆配置
-keep class com.baidu.** {*;}
-keep class mapsdkvi.com.** {*;}

# ButterKnife混淆配置
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

# OkHttp3混淆配置
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**

# Retrofit2混淆配置
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions

# RxJava、RxAndroid混淆配置
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
   long producerIndex;
   long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode consumerNode;
}

# Glide混淆配置
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

# Picasso混淆配置
-keep class com.parse.*{ *; }
-dontwarn com.parse.**
-dontwarn com.squareup.picasso.**
-keepclasseswithmembernames class * {
    native <methods>;
}

# Fastjson混淆配置
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.**{*; }

# Gson混淆配置
-keep class com.google.gson.** {*;}
-keep class com.google.**{*;}
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }

# GreenDao混淆配置
-keep class de.greenrobot.dao.** {*;}
-keepclassmembers class * extends de.greenrobot.dao.AbstractDao {
    public static Java.lang.String TABLENAME;
}
-keep class **$Properties

# 高徳地圖混淆配置
-dontwarn com.amap.api.**
-dontwarn com.a.a.**
-dontwarn com.autonavi.**
-keep class com.amap.api.**  {*;}
-keep class com.autonavi.**  {*;}
-keep class com.a.a.**  {*;}

# Bugly混淆配置
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
# tinker
-dontwarn com.tencent.tinker.**
-keep class com.tencent.tinker.** { *; }
-keep class androidx.**{*;}

#EventBus 3.0.x
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

# umeng混淆規(guī)則
-dontwarn com.umeng.**
-dontwarn com.taobao.**
-dontwarn anet.channel.**
-dontwarn anetwork.channel.**
-dontwarn org.android.**
-dontwarn org.apache.thrift.**
-dontwarn com.xiaomi.**
-dontwarn com.huawei.**
-dontwarn com.meizu.**
-keepattributes *Annotation*
-keep class com.taobao.** {*;}
-keep class org.android.** {*;}
-keep class anet.channel.** {*;}
-keep class com.umeng.** {*;}
-keep class com.xiaomi.** {*;}
-keep class com.huawei.** {*;}
-keep class com.meizu.** {*;}
-keep class org.apache.thrift.** {*;}
-keep class com.alibaba.sdk.android.**{*;}
-keep class com.ut.**{*;}
-keep class com.ta.**{*;}
-keep public class **.R$*{
   public static final int *;
}

總結(jié)哪些不應(yīng)該混淆

  • 使用了自定義控件那么要保證它們不參與混淆
  • 使用了枚舉要保證枚舉不被混淆
  • 對第三方庫中的類不進行混淆
  • 運用了反射的類也不進行混淆
  • 使用了 Gson 之類的工具要使 JavaBean 類即實體類不被混淆
  • 在引用第三方庫的時候栈暇,一般會標(biāo)明庫的混淆規(guī)則的麻裁,建議在使用的時候就把混淆規(guī)則添加上去,免得到最后才去找
  • 有用到 WebView 的 JS 調(diào)用也需要保證寫的接口方法不混淆源祈,原因和第一條一樣
  • Parcelable 的子類和 Creator 靜態(tài)成員變量不混淆煎源,否則會產(chǎn)生 Android.os.BadParcelableException 異常
  • 使用的四大組件,自定義的Application* 實體類
  • JNI中調(diào)用的類
  • Layout布局使用的View構(gòu)造函數(shù)(自定義控件)香缺、android:onClick等薪夕。

結(jié)束語

若還有不清楚的可以直接查看官網(wǎng):https://www.guardsquare.com/en/products/proguard/manual/introduction

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市赫悄,隨后出現(xiàn)的幾起案子原献,更是在濱河造成了極大的恐慌,老刑警劉巖埂淮,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姑隅,死亡現(xiàn)場離奇詭異,居然都是意外死亡倔撞,警方通過查閱死者的電腦和手機讲仰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痪蝇,“玉大人鄙陡,你說我怎么就攤上這事□飭” “怎么了趁矾?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長给僵。 經(jīng)常有香客問我毫捣,道長,這世上最難降的妖魔是什么帝际? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任蔓同,我火速辦了婚禮,結(jié)果婚禮上蹲诀,老公的妹妹穿的比我還像新娘斑粱。我一直安慰自己,他們只是感情好脯爪,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布则北。 她就那樣靜靜地躺著蹋宦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咒锻。 梳的紋絲不亂的頭發(fā)上冷冗,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音惑艇,去河邊找鬼蒿辙。 笑死,一個胖子當(dāng)著我的面吹牛滨巴,可吹牛的內(nèi)容都是我干的思灌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼恭取,長吁一口氣:“原來是場噩夢啊……” “哼泰偿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蜈垮,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤耗跛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后攒发,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體调塌,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年惠猿,在試婚紗的時候發(fā)現(xiàn)自己被綠了羔砾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡偶妖,死狀恐怖姜凄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情趾访,我是刑警寧澤态秧,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站腹缩,受9級特大地震影響屿聋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜藏鹊,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望转锈。 院中可真熱鬧盘寡,春花似錦、人聲如沸撮慨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至影涉,卻和暖如春变隔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蟹倾。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工匣缘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鲜棠。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓肌厨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親豁陆。 傳聞我的和親對象是個殘疾皇子柑爸,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 聲明 這篇文章更多的是做一個整理,內(nèi)容來自于ProGuard官方文檔以及各種博客等盒音,相關(guān)文章的鏈接在參考目錄里表鳍,感...
    夷陵小祖閱讀 3,682評論 0 23
  • 什么是代碼混淆 代碼混淆就是將代碼中的各種元素,如變量祥诽,方法进胯,類和包的名字改寫成無意義的名字,增加項目反編譯后被讀...
    蝸牛家族史閱讀 5,144評論 1 4
  • 2016-10-23光源coder 轉(zhuǎn)載自 http://www.reibang.com/writer#/note...
    淡如茶2016閱讀 1,080評論 0 8
  • 混淆是打包過程中最重要的流程之一原押,在沒有特殊原因的情況下胁镐,所有 app 都應(yīng)該開啟混淆。 首先诸衔,這里說的的混淆其實...
    瀟瀟code閱讀 1,547評論 0 5
  • android混淆打包盯漂,可提高apk的安全性,去除沒用的資源笨农,減小apk的體積就缆。(PS:雖說高手還是能反編譯)bu...
    JackChenFeng閱讀 5,865評論 0 1