關(guān)于作者:CSDN內(nèi)容合伙人、技術(shù)專家, 從零開始做日活千萬級(jí)APP。
專注于分享各領(lǐng)域原創(chuàng)系列文章 ,擅長java后端、移動(dòng)開發(fā)、人工智能等,希望大家多多支持。
一、導(dǎo)讀
我們繼續(xù)總結(jié)學(xué)習(xí)基礎(chǔ)知識(shí),溫故知新。
本文講述Android Proguard 相關(guān)知識(shí)。
二、概覽
Proguard 四部曲:
shrink(刪減):刪減無用代碼,包括類、變量、方法和屬性,縮減了APK包的大小
optimize(優(yōu)化):優(yōu)化方法字節(jié)碼,并移除無用的構(gòu)造方法
obfuscate(混淆):混淆現(xiàn)有代碼,將有意義的命名替換為無意義的命名
preverify(預(yù)校驗(yàn)):給類添加預(yù)校驗(yàn)信息,這是J2ME和Java 6及以上要求的
proguard 文檔
三、語法規(guī)則
3.1 輸入/輸出選項(xiàng)
@ filename
“文件名”的縮寫 ‘-include filename’.
-include filename
從給定文件filename遞歸讀取配置選項(xiàng)
-basedirectory directoryname
指定這些配置參數(shù)或此配置文件中所有后續(xù)相對(duì)文件名的基目錄
-injars class_path
指定要處理的應(yīng)用程序的輸入 jar(或 apks、aabs、aars、wars、ears、jmods、zip 或目錄)。
可以使用多個(gè)-injars選項(xiàng)指定類路徑條目。
-outjars class_path
指定輸出 jar 的名稱(或 apks、aabs、aars、wars、ears、jmods、zips 或目錄)。
為了更好的可讀性,可以使用多個(gè)-outjars選項(xiàng)指定類路徑條目。如果沒有任何-outjars選項(xiàng),則不會(huì)編寫任何 jars
-libraryjars class_path
指定要處理的應(yīng)用程序的庫 jar(或 apks、aabs、aars、wars、ears、jmods、zips、目錄)
-skipnonpubliclibraryclasses
指定在讀取庫 jar 時(shí)跳過非公共類,以加快處理速度并減少 ProGuard 的內(nèi)存使用量
-dontskipnonpubliclibraryclasses
指定不忽略非公共庫類。從版本 4.5 開始,這是默認(rèn)設(shè)置
-dontskipnonpubliclibraryclassmembers
指定不忽略包可見的庫類成員(字段和方法)
-keepdirectories [directory_filter]
指定要保留在輸出 jar 中的目錄(或 apks、aabs、aars、wars、ears、jmods、zips 或目錄)
-target version
已棄用:此選項(xiàng)僅適用于 Java 類文件版本 <= 11
-forceprocessing
指定處理輸入,即使輸出看起來是最新的
3.2 保留選項(xiàng)
-keep [,modifier,...] class_specification
-keepnames class_specification
指定要保留為代碼入口點(diǎn)的類和類成員(字段和方法)
-keepclassmembers [,modifier,...] class_specification
-keepclassmembernames class_specification
指定要保留的類成員(如果它們的類也被保留)
-keepclasseswithmembers [,modifier,...] class_specification
-keepclasseswithmembernames class_specification
指定要保留的類和類成員,前提是所有指定的類成員都存在
-if class_specification
指定必須present激活后續(xù)保留選項(xiàng)(-keep、-keepclassmembers、…)的類和類成員。
條件和后續(xù)的 keep 選項(xiàng)可以共享通配符和對(duì)通配符的引用。例如,您可以使用Dagger和Butterknife等框架保留類,前提是項(xiàng)目中存在具有相關(guān)名稱的類。
-printseeds [filename]
指定詳盡列出與各種-keep選項(xiàng)匹配的類和類成員。該列表將打印到標(biāo)準(zhǔn)輸出或給定文件。該列表可用于驗(yàn)證是否確實(shí)找到了預(yù)期的類成員,
特別是在您使用通配符時(shí)。例如,您可能想要列出您保留的所有應(yīng)用程序或所有小程序。
3.3 縮小選項(xiàng)
-dontshrink
指定不收縮輸入。默認(rèn)情況下,ProGuard 會(huì)縮小代碼:它會(huì)刪除所有未使用的類和類成員。它只保留各種-keep選項(xiàng)列出的選項(xiàng)以及它們直接或間接依賴的選項(xiàng)。
它還在每個(gè)優(yōu)化步驟之后應(yīng)用收縮步驟,因?yàn)槟承﹥?yōu)化可能會(huì)提供刪除更多類和類成員的可能性。
-printusage [filename]
指定列出輸入類文件的死代碼。該列表將打印到標(biāo)準(zhǔn)輸出或給定文件。例如,您可以列出應(yīng)用程序未使用的代碼。僅適用于收縮時(shí)。
-whyareyoukeeping class_specification
指定打印有關(guān)為何給定類和類成員保留在收縮步驟中的詳細(xì)信息。如果您想知道為什么某些給定元素出現(xiàn)在輸出中,這可能很有用。
3.4 優(yōu)化選項(xiàng)
-dontoptimize
指定不優(yōu)化輸入類文件。默認(rèn)情況下,ProGuard 會(huì)優(yōu)化所有代碼。它內(nèi)聯(lián)和合并類和類成員,并在字節(jié)碼級(jí)別優(yōu)化所有方法。
-optimizations optimization_filter
以更細(xì)粒度的級(jí)別指定要啟用和禁用的優(yōu)化。僅適用于優(yōu)化時(shí)
例如:
# 指定混淆是采用的算法,后面的參數(shù)是一個(gè)過濾器
# 這個(gè)過濾器是谷歌推薦的算法,一般不做更改
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-optimizationpasses n
指定代碼的壓縮級(jí)別 0 - 7(指定代碼進(jìn)行迭代優(yōu)化的次數(shù),在Android里面默認(rèn)是5,這條指令也只有在可以優(yōu)化時(shí)起作用。)
-assumenosideeffects class_specification
指定除了可能返回值之外沒有任何副作用的方法。例如,該方法System.currentTimeMillis()返回一個(gè)值,但它沒有任何副作用。
在優(yōu)化步驟中,如果 ProGuard 可以確定未使用返回值,則可以刪除對(duì)此類方法的調(diào)用。ProGuard 會(huì)分析您的程序代碼以自動(dòng)查找此類方法。
它不會(huì)分析庫代碼,因此此選項(xiàng)很有用。例如,您可以指定 method System.currentTimeMillis(),以便刪除對(duì)其的任何空閑調(diào)用。如果小心的話,
您還可以使用該選項(xiàng)來刪除日志記錄代碼。請(qǐng)注意,ProGuard 將該選項(xiàng)應(yīng)用于指定方法的整個(gè)層次結(jié)構(gòu)。僅適用于優(yōu)化時(shí)。一般來說,做出假設(shè)可能是危險(xiǎn)的。
您可以輕松地破壞已處理的代碼。僅當(dāng)您知道自己在做什么時(shí)才使用此選項(xiàng)!
-assumenoexternalsideeffects class_specification
-assumenoescapingparameters class_specification
-assumenoexternalreturnvalues class_specification
-assumevalues class_specification
-allowaccessmodification
-mergeinterfacesaggressively
-optimizeaggressively
代碼優(yōu)化相關(guān),用不好容易出問題。
3.5 混淆選項(xiàng)
-dontobfuscate
指定不混淆輸入類文件。默認(rèn)情況下,ProGuard 會(huì)混淆代碼:它為類和類成員分配新的短隨機(jī)名稱。它刪除了僅對(duì)調(diào)試有用的內(nèi)部屬性,例如源文件名、變量名和行號(hào)。
-printmapping [filename]
指定打印已重命名的類和類成員從舊名稱到新名稱的映射。映射被打印到標(biāo)準(zhǔn)輸出或給定文件。例如,后續(xù)增量混淆需要它,或者如果您想再次理解混淆的堆棧跟蹤。僅在混淆時(shí)適用。
-applymapping filename
指定重用在 ProGuard 的先前混淆運(yùn)行中打印出的給定名稱映射。映射文件中列出的類和類成員接收與其一起指定的名稱。未提及的類和類成員將獲得新名稱。
該映射可以引用輸入類以及庫類。此選項(xiàng)對(duì)于增量混淆非常有用,即處理現(xiàn)有代碼片段的附加組件或小補(bǔ)丁。如果代碼結(jié)構(gòu)發(fā)生根本性變化,ProGuard 可能會(huì)打印出應(yīng)用映射導(dǎo)致沖突的警告。
您可以通過-useuniqueclassmembernames在兩次混淆運(yùn)行中指定該選項(xiàng)來降低這種風(fēng)險(xiǎn)。只允許使用單個(gè)映射文件。僅在混淆時(shí)適用。
-obfuscationdictionary proguard-dic.txt //指定一個(gè)字典文件作為混淆字典
-classobfuscationdictionary proguard-dic.txt //類字典
-packageobfuscationdictionary proguard-dic.txt //包字典
-overloadaggressively
指定在混淆時(shí)應(yīng)用積極的重載。然后,多個(gè)字段和方法可以獲得相同的名稱,只要它們的參數(shù)和返回類型不同,如 Java 字節(jié)碼所要求的(不僅僅是它們的參數(shù),如 Java 語言所要求的)。
此選項(xiàng)可以使處理后的代碼更小(并且更難以理解,大小,體積)。僅在混淆時(shí)適用。
但是可能存在問題,如Google 的 Dalvik VM 無法處理過載的靜態(tài)字段。
-useuniqueclassmembernames
指定將相同的混淆名稱分配給具有相同名稱的類成員,并將不同的混淆名稱分配給具有不同名稱的類成員(對(duì)于每個(gè)給定的類成員簽名)。如果沒有該選項(xiàng),更多的類成員可以映射到相同的短名稱,如“a”、“b”等。因此,
該選項(xiàng)會(huì)稍微增加結(jié)果代碼的大小,但它確保保存的混淆名稱映射始終可以在后續(xù)增量混淆步驟中受到尊重
-dontusemixedcaseclassnames
指定在混淆時(shí)不生成大小寫混合的類名。默認(rèn)情況下,混淆的類名可以包含大寫字符和小寫字符的混合。
-keeppackagenames [package_filter]
指定不混淆給定的包名稱。
-flattenpackagehierarchy [package_name]
指定通過將重命名的所有包移動(dòng)到單個(gè)給定父包中來重新打包它們。如果不帶參數(shù)或使用空字符串 (‘’),包將移至根包中。此選項(xiàng)是進(jìn)一步混淆包名稱的示例之一。它可以使處理后的代碼更小且更難以理解(大小,體積)。僅在混淆時(shí)適用。
與 repackageclasses 沖突
-repackageclasses [package_name]
指定通過將重命名的所有類文件移動(dòng)到單個(gè)給定包中來重新打包它們。如果沒有參數(shù)或使用空字符串 (‘’),則包將被完全刪除。該選項(xiàng)會(huì)覆蓋該-flattenpackagehierarchy選項(xiàng)。這是進(jìn)一步混淆包名稱的另一個(gè)例子。
它可以使處理后的代碼變得更小并且更難以理解(大小,體積)。它的已棄用名稱是-defaultpackage. 僅在混淆時(shí)適用。
-keepattributes [attribute_filter]
指定要保留的任何可選屬性??梢允褂靡粋€(gè)或多個(gè)指令來指定屬性-keepattributes
# 拋出異常時(shí)保留代碼行號(hào)
-keepattributes SourceFile,LineNumberTable
# 保護(hù)代碼中的Annotation不被混淆
-keepattributes *Annotation*
# 避免混淆泛型, 這在JSON實(shí)體映射時(shí)非常重要
-keepattributes Signature
-keepparameternames
指定保留所保留方法的參數(shù)名稱和類型。該選項(xiàng)實(shí)際上保留了調(diào)試屬性LocalVariableTable和LocalVariableTypeTable
-renamesourcefileattribute [string]
指定要放入類文件的SourceFile屬性(和屬性)中的常量字符串。SourceDir請(qǐng)注意,該屬性必須首先存在,因此還必須使用-keepattributes指令顯式保留它。
例如,您可能希望讓經(jīng)過處理的庫和應(yīng)用程序生成有用的模糊堆棧跟蹤。僅在混淆時(shí)適用。
-keepkotlinmetadata
已棄用:使用-keep class kotlin.Metadata替代。指定處理kotlin.Metadata注釋(如果存在)。目前僅支持對(duì)其內(nèi)容進(jìn)行縮小和混淆。如果啟用此選項(xiàng),則應(yīng)從優(yōu)化中排除包含此類注釋的類。
-adaptclassstrings [class_filter]
指定與類名相對(duì)應(yīng)的字符串常量也應(yīng)該被混淆。如果沒有過濾器,所有與類名相對(duì)應(yīng)的字符串常量都會(huì)被調(diào)整。
-adaptresourcefilenames [file_filter]
根據(jù)相應(yīng)類文件(如果有)的混淆名稱指定要重命名的資源文件。如果沒有過濾器,則與類文件對(duì)應(yīng)的所有資源文件都會(huì)被重命名。
-adaptresourcefilecontents [file_filter]
指定要更新內(nèi)容的資源文件和本機(jī)庫。資源文件中提到的任何類名都會(huì)根據(jù)相應(yīng)類(如果有)的混淆名稱進(jìn)行重命名。
3.6 預(yù)驗(yàn)證選項(xiàng)
-dontpreverify
指定不對(duì)已處理的類文件進(jìn)行預(yù)驗(yàn)證。
-microedition
指定處理的類文件針對(duì) Java Micro Edition。
-android
指定處理的類文件是針對(duì)Android平臺(tái)的
3.7 常規(guī)選項(xiàng)
-verbose
指定在處理過程中寫出更多信息。如果程序因異常而終止,此選項(xiàng)將打印出整個(gè)堆棧跟蹤,而不僅僅是異常消息。
-dontnote [class_filter]
指定不打印有關(guān)配置中潛在錯(cuò)誤或遺漏的注釋,例如類名稱中的拼寫錯(cuò)誤或缺少可能有用的選項(xiàng)。可選的過濾器是正則表達(dá)式;ProGuard 不會(huì)打印有關(guān)具有匹配名稱的類的注釋。
-dontwarn [class_filter]
指定根本不警告未解決的引用和其他重要問題??蛇x的過濾器是正則表達(dá)式;ProGuard 不會(huì)打印有關(guān)具有匹配名稱的類的警告。忽視警告可能會(huì)很危險(xiǎn)。
-ignorewarnings
指定打印有關(guān)未解決的引用和其他重要問題的任何警告,但在任何情況下都繼續(xù)處理。忽視警告可能會(huì)很危險(xiǎn)。屏蔽警告
-printconfiguration [filename]
指定寫出已解析的整個(gè)配置,包括包含的文件和替換的變量。該結(jié)構(gòu)被打印到標(biāo)準(zhǔn)輸出或給定文件。
-dump [filename]
指定在任何處理之后寫出類文件的內(nèi)部結(jié)構(gòu)。該結(jié)構(gòu)被打印到標(biāo)準(zhǔn)輸出或給定文件。
-addconfigurationdebugging
指定使用調(diào)試語句來檢測已處理的代碼,這些調(diào)試語句會(huì)打印出缺少 ProGuard 配置的建議。
四、過濾器
? 匹配名稱中的任何 單個(gè) 字符。 例如,“ com.example.Test?”匹配“ com.example.Test1”和“ com.example.Test2”,但不匹配“ com.example.Test12”。
* 匹配名稱中不包含包分隔符或目錄分隔符的任何部分。
例如,“ com.example.*Test*”匹配“ com.example.Test”和“ com.example.YourTestApplication”,但不匹配“ com.example.mysubpackage.MyTest”。
或者,更一般地說,“ com.example.*”匹配“ com.example”中的所有類,但不匹配其子包中的所有類。
** 匹配名稱的任何部分,可能包含任意數(shù)量的包分隔符或目錄分隔符。
<n> 匹配同一選項(xiàng)中第n個(gè)匹配的通配符。例如,“ com.example.*Foo<1>”匹配“ com.example.BarFooBar”。
例如,“ java/**.class,javax/**.class”匹配 和 中的所有類java文件javax。
此外,文件名前面可以有感嘆號(hào)“ ! ” '從進(jìn)一步嘗試與后續(xù)文件名匹配中排除該文件名。
例如,“ !**.gif,images/**”匹配images目錄中除 gif 文件之外的所有文件。
忽略輸入 jar 中的某些文件,images此配置會(huì)刪除該目錄及其子目錄中的所有文件。
-injars in.jar(!images/**)
-outjars out.jar
僅保留第一個(gè)輸入 jar 中的清單文件:
-injars in1.jar
-injars in2.jar(!META-INF/MANIFEST.MF)
-injars in3.jar(!META-INF/MANIFEST.MF)
-outjars out.jar
例如,“ foo,*bar”匹配名稱foo以及所有以 結(jié)尾的名稱bar。
<init> 匹配任何構(gòu)造函數(shù)。
<fields> 匹配任何字段。
<methods> 匹配任何方法。
* 匹配任何字段或方法。
通配符 意義
% 匹配任何原始類型(" boolean"、" int" 等)或 " void" 類型。
? 匹配類名中的任何單個(gè)字符。
* 匹配類名中不包含包分隔符的任何部分。
** 匹配類名的任何部分,可能包含任意數(shù)量的包分隔符。
*** 匹配任何類型(原始或非原始、數(shù)組或非數(shù)組)。
... 匹配任意數(shù)量任意類型的參數(shù)。
<n> 匹配同一選項(xiàng)中第n個(gè)匹配的通配符。
請(qǐng)注意?,、 和通配符永遠(yuǎn)不會(huì)匹配原始類型。此外,只有通配符才能匹配任何維度的數(shù)組類型。例如,“ ** get*()”匹配“ java.lang.Object getObject()”,
但不匹配“ float getFloat()”,也不匹配“ java.lang.Object[] getObjects()”。
4.1 增量混淆
-injars proguardgui.jar
-outjars proguardgui_out.jar
-injars proguard.jar
-outjars proguard_out.jar
-libraryjars <java.home>/jmods/java.base.jmod(!**.jar;!module-info.class)
-applymapping proguard.map
-keep public class proguard.gui.ProGuardGUI {
public static void main(java.lang.String[]);
}
4.2 尋找未使用的代碼及方法等(廢棄代碼)
#不進(jìn)行優(yōu)化,建議使用此選項(xiàng),
-dontoptimize
#指定不混淆輸入類文件。默認(rèn)情況下,ProGuard 會(huì)混淆代碼:它為類和類成員分配新的短隨機(jī)名稱。它刪除了僅對(duì)調(diào)試有用的內(nèi)部屬性,例如源文件名、變量名和行號(hào)。
-dontobfuscate
# 不進(jìn)行預(yù)校驗(yàn),Android不需要,可加快混淆速度。
-dontpreverify
#指定列出輸入類文件的死代碼。該列表將打印到標(biāo)準(zhǔn)輸出或給定文件。例如,您可以列出應(yīng)用程序未使用的代碼。僅適用于收縮時(shí)。
-printusage
點(diǎn)擊build后,可以看到如下的輸出,列出了幾個(gè)沒有使用到的類及方法
> Task :app:minifyReleaseWithR8
org.fmod.example.CallBack
org.fmod.example.CallBackManager
org.fmod.example.DeadClass
org.fmod.example.MemoryShakeActivity:
public void dpOperate()
public void testa()
public void testb()
org.fmod.example.BuildConfig
org.fmod.example.R$color
org.fmod.example.R$drawable
org.fmod.example.R$id
org.fmod.example.R$layout
org.fmod.example.R$mipmap
org.fmod.example.R$string
org.fmod.example.R$style
org.fmod.example.R$xml
org.fmod.example.R
org.fmod.example.databinding.ActivityMemoryBinding:
public final android.widget.Button btMemory
private void <init>(android.widget.FrameLayout,android.widget.Button)
public static org.fmod.example.databinding.ActivityMemoryBinding bind(android.view.View)
public static org.fmod.example.databinding.ActivityMemoryBinding inflate(android.view.LayoutInflater)
public static org.fmod.example.databinding.ActivityMemoryBinding inflate(android.view.LayoutInflater,android.view.ViewGroup,boolean)
androidx.core.location.LocationManagerCompat$$InternalSyntheticLambda$1$196e0315f48caa68131c5d4d780ff53e9618a06658f902ea94f753d0df163305$1
androidx.core.location.LocationManagerCompat:
public static synthetic java.lang.Boolean $r8$lambda$JLIcm4BkQpukCiUbhX4BKZUICt4(android.location.LocationManager,androidx.core.location.LocationManagerCompat$GpsStatusTransport)
#不進(jìn)行優(yōu)化,建議使用此選項(xiàng),
-dontoptimize
#指定不混淆輸入類文件。默認(rèn)情況下,ProGuard 會(huì)混淆代碼:它為類和類成員分配新的短隨機(jī)名稱。它刪除了僅對(duì)調(diào)試有用的內(nèi)部屬性,例如源文件名、變量名和行號(hào)。
-dontobfuscate
# 不進(jìn)行預(yù)校驗(yàn),Android不需要,可加快混淆速度。
-dontpreverify
#指定列出輸入類文件的死代碼。該列表將打印到標(biāo)準(zhǔn)輸出或給定文件。例如,您可以列出應(yīng)用程序未使用的代碼。僅適用于收縮時(shí)。
-printusage
-keep public class org.fmod.example.DeadClass {
public static void main(java.lang.String[]);
}
如果我們將某一個(gè)未使用的class 進(jìn)行keep,則結(jié)果如下
> Task :app:minifyReleaseWithR8
org.fmod.example.BuildConfig
org.fmod.example.CallBack
org.fmod.example.CallBackManager
org.fmod.example.DeadClass:
public void testa()
public void testb()
public void testc()
org.fmod.example.MemoryShakeActivity:
public void dpOperate()
public void testa()
public void testb()
org.fmod.example.R$color
org.fmod.example.R$drawable
org.fmod.example.R$id
org.fmod.example.R$layout
org.fmod.example.R$mipmap
org.fmod.example.R$string
org.fmod.example.R$style
org.fmod.example.R$xml
org.fmod.example.R
org.fmod.example.databinding.ActivityMemoryBinding:
public final android.widget.Button btMemory
private void <init>(android.widget.FrameLayout,android.widget.Button)
public static org.fmod.example.databinding.ActivityMemoryBinding bind(android.view.View)
public static org.fmod.example.databinding.ActivityMemoryBinding inflate(android.view.LayoutInflater)
public static org.fmod.example.databinding.ActivityMemoryBinding inflate(android.view.LayoutInflater,android.view.ViewGroup,boolean)
androidx.core.location.LocationManagerCompat$$InternalSyntheticLambda$1$196e0315f48caa68131c5d4d780ff53e9618a06658f902ea94f753d0df163305$1
androidx.core.location.LocationManagerCompat:
public static synthetic java.lang.Boolean $r8$lambda$JLIcm4BkQpukCiUbhX4BKZUICt4(android.location.LocationManager,androidx.core.location.LocationManagerCompat$GpsStatusTransport)
五、混淆基本原則
項(xiàng)目中以下類不應(yīng)該混淆
5.1 系統(tǒng)相關(guān)類不要混淆
- 四大組件:如 Activity、Service、Provider、Broadcast及其Fragment等系統(tǒng)相關(guān)類
#繼承activity,application,service,broadcastReceiver,contentprovider....不進(jìn)行混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.support.multidex.MultiDexApplication
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-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 * extends android.support.v4.app.Fragment
-keep public class * extends androidx.fragment.app.Fragment
-keep public class * extends android.content.ContentProvider
- view(WebView)相關(guān)類
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
#不混淆任何一個(gè)View中的setXxx()和getXxx()方法,
#因?yàn)閷傩詣?dòng)畫需要有相應(yīng)的setter和getter的方法實(shí)現(xiàn)
-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);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
- 枚舉類
#不混淆枚舉中的values()和valueOf()方法
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
- 注解
- support下的所有類及其內(nèi)部類
-keep class android.support.** {*;}## 保留support下的所有類及其內(nèi)部類
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**
- Serializable
# 繼承Serizalizable的類的如下成員不被移除混淆
-keepclassmembers class * implements java.io.Serializable {
java.lang.Object writeReplace();
java.lang.Object readResolve();
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
}
- Parcelable的子類和Creator靜態(tài)成員變量
#不混淆Parcelable實(shí)現(xiàn)類中的CREATOR字段,
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
5.2 部分項(xiàng)目相關(guān)類不要混淆
- 數(shù)據(jù)模型(各種數(shù)據(jù)模型類,GSON、fastjson等框架解析服務(wù)端數(shù)據(jù)時(shí),混淆后解析不了)
-keep class com.xxx.entity.** {*;}
- Jni接口和java的native方法 (這個(gè)方法需要和native方法保持一致,混淆后找不到會(huì)報(bào)錯(cuò))
-keepclasseswithmembernames class * {
native <methods>;
}
-
Java接口 (主要針對(duì)對(duì)外開放的接口)
-
調(diào)用反射的地方 ()
-
抽象內(nèi)部類
比如Animal的內(nèi)部類不混淆
-keep class com.xxx.demo.Animal{*;}
-keep class com.xxx.demo.Animal$*{*;}
- 使用到的第三方開源庫或者引用其他第三方的SDK包
# 微信支付
-keep class com.tencent.mm.opensdk.** {*; }
- AOP或者讀取路徑等的地方
整理了一個(gè)基礎(chǔ)混淆文件:
Android通用混淆文件
5.3、添加混淆字典
為了是混淆更混亂,可以添加自定義的混淆字典
-classobfuscationdictionary proguard-dic.txt //類字典
-obfuscationdictionary proguard-dic.txt //混淆字典
-packageobfuscationdictionary proguard-dic.txt //包字典
混淆字典下載地址
5.4 r8 & proguard
如果不想用R8,想用回ProGuard的話,可以在gradle.properties文件中添加下述配置禁用R8:
android.enableR8=false
android.enableR8.libraries=false
Android在打包后,一般會(huì)有以下幾個(gè)文件:
mapping.txt、usage.txt 等
mapping.txt→ 原始與混淆過的類、方法、字段名稱間的轉(zhuǎn)換關(guān)系;
seeds.txt→ 未進(jìn)行混淆的類與成員;
usage.txt→ APK中移除的代碼;即廢棄代碼
configuration.txt→
missing_rules.txt
resources.txt→ 資源優(yōu)化記錄文件,哪些資源引用了其他資源,哪些資源在使用,哪些資源被移除;
參考
proguard 文檔
六、 推薦閱讀
Java 專欄
SQL 專欄
數(shù)據(jù)結(jié)構(gòu)與算法
Android學(xué)習(xí)專欄文章來源:http://www.zghlxwxcb.cn/news/detail-752470.html
未經(jīng)允許不得轉(zhuǎn)載文章來源地址http://www.zghlxwxcb.cn/news/detail-752470.html
到了這里,關(guān)于Android Proguard混淆的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!