說明:本文參考(翻譯)自Android SDK根目錄下的proguard目錄下的說明文檔鸭轮,是其中的一篇。橄霉,文中除了翻譯外加了一些作者的實(shí)際驗(yàn)證窃爷。文章對(duì)Android混淆規(guī)則做一個(gè)解釋說明。作者才疏學(xué)淺姓蜂,如有錯(cuò)誤按厘,請(qǐng)諒解!<@_@>
Android混淆入門可參考《Android 代碼混淆零基礎(chǔ)入門》
Input/Output Options 輸入輸出選項(xiàng)
-include filename
遞歸引入目錄的配置文件
-basedirectory directoryname
-injars class_path
指定應(yīng)用程序要處理的jars包(或者wars钱慢、ears逮京、zip、或者目錄結(jié)構(gòu))束莫,它們里面的class文件會(huì)被處理并被寫入到輸出jars里面懒棉。它們里面的任何非class文件會(huì)被直接復(fù)制過去但是不會(huì)處理草描。(需要注意過濾調(diào)一些IDE自動(dòng)生成的文件);
-outjars class_path
指定輸出jars(wars策严、ears穗慕、zip、目錄結(jié)構(gòu))的名稱妻导;由-injars 指定的被處理的jars將被寫入到指定的輸出jars里揍诽。如果不指定outjars將不會(huì)有class文件被寫入。
-libraryjars class_path 不混淆指定的jar庫(android 項(xiàng)目中一般不混淆引入的第三方類庫)
-skipnonpubliclibraryclasses 不混淆指定jars中的非public calsses
-dontskipnonpubliclibraryclasses 不忽略指定jars中的非public calsses (默認(rèn)選項(xiàng))和上面的選手想對(duì)
-dontskipnonpubliclibraryclassmembers
不忽略指定類庫的public類成員(變量和方法)栗竖,默認(rèn)情況下暑脆,ProGuard會(huì)忽略他們
-keepdirectories [directory_filter] 指定要保持的目錄結(jié)構(gòu),默認(rèn)情況下會(huì)刪除所有目錄以減小jar的大小狐肢。
-target version
指定java版本號(hào)添吗。 版本號(hào)可以是1.0,1.1,1.2,1.3,1.4,1.5(或僅5),1.6(或僅6)或1.7(或僅7)中的一個(gè)份名。 默認(rèn)情況下碟联,類文件的版本號(hào)保持不變。 例如僵腺,您可能想要將類文件升級(jí)到Java 6鲤孵,通過更改其版本號(hào)并對(duì)其進(jìn)行預(yù)驗(yàn)證。
-forceprocessing 強(qiáng)制處理輸入(-injars)jars辰如。即使輸出jars是最新的普监。通過指定的輸入,輸出和配置文件或者目錄的時(shí)間戳判斷是否最新琉兜。
Keep Options 保留選項(xiàng)
-keep [,modifier凯正,...] class_specification
指定需要保留的類和類成員(作為公共類庫,應(yīng)該保留所有可公開訪問的public方法)
-keepclassmembers [,modifier豌蟋,...] class_specification
指定需要保留的類成員:變量或者方法
-keepclasseswithmembers [,modifier廊散,...] class_specification
指定保留的類和類成員,條件是所指定的類成員都存在(既在壓縮階段沒有被刪除的成員梧疲,效果和keep差不多)
-keepnames class_specification
[-keep allowshrinking class_specification 的簡(jiǎn)寫]
指定要保留名稱的類和類成員允睹,前提是在壓縮階段未被刪除。僅用于模糊處理
-keepclassmembernames class_specification
[-keepclassmembers allowshrinking class_specification 的簡(jiǎn)寫]
指定要保留名稱的類成員幌氮,前提是在壓縮階段未被刪除缭受。僅用于模糊處理
-keepclasseswithmembernames class_specification
[-keepclasseswithmembers allowshrinking class_specification 的簡(jiǎn)寫]
指定要保留名稱的類成員,前提是在壓縮階段后所指定的類成員都存在浩销。僅用于模糊處理
-printseeds [filename]
指定詳盡列出由各種-keep選項(xiàng)匹配的類和類成員贯涎。 列表打印到標(biāo)準(zhǔn)輸出或給定文件。 該列表可用于驗(yàn)證是否真的找到了預(yù)期的類成員慢洋,特別是如果您使用通配符塘雳。 例如陆盘,您可能想要列出所有應(yīng)用程序或您保存的所有小程序。
Keep選項(xiàng)概述對(duì)比(Overview of Keep Options)
作用范圍 | 保持所指定類败明、成員 | 所指定類隘马、成員在壓縮階段沒有被刪除,才能被保持 |
---|---|---|
類和類成員 | -keep | -keepnames |
僅類成員 | -keepclassmembers | -keepclassmembernames |
類和類成員(前提是成員都存在) | -keepclasseswithmembers | -keepclasseswithmembernames |
- 建議初學(xué)者妻顶,如果不確定用那個(gè)keep選項(xiàng)就盡量用-keep酸员,這個(gè)比較簡(jiǎn)單且不易使混淆代碼出錯(cuò)。
- 如果只指定類被保留讳嘱,那么它的成員同樣可能會(huì)被壓縮幔嗦、優(yōu)化或者混淆。
- 如果指定類成員被保留沥潭,那么其他代碼也有可能會(huì)被壓縮邀泉、優(yōu)化或者混淆
Keep命令修飾符說明 [,modifier,...] :
可用在keep钝鸽、keepclassmembers汇恤、keepclasseswithmembers命令后面
- allowshrinking 指定對(duì)象可能會(huì)被壓縮,即使他們被keep選項(xiàng)保留拔恰。如果所指定的對(duì)象不是必需的因谎,則他們可能會(huì)被刪出(在壓縮步驟)。反之如果他們是必須的颜懊,則他們可能不會(huì)被優(yōu)化或者混淆财岔。
如: 類ClassOneThree在代碼中并沒有被引用,是一個(gè)沒有使用的類.
-keep class com.dev.demo.one.ClassOneThree*{*;}
-keep命令讓上ClassOneThree保留下來,但是如果加了allowshrinking 修飾符結(jié)果就不一樣了饭冬,下面這2條命令效果其實(shí)是一樣的:ClassOneThree在壓縮階段就被刪除了使鹅,沒有被保留,因?yàn)樗]有被引用到昌抠。
-keepnames class com.dev.demo.one.ClassOneThree*{*;}```
- ***allowoptimization*** 指定對(duì)象可能會(huì)被優(yōu)化,即使他們被keep選項(xiàng)保留鲁僚。所指定對(duì)象可能會(huì)被改變(優(yōu)化步驟)炊苫,但可能不會(huì)被混淆或者刪除。該修飾符只對(duì)實(shí)現(xiàn)異常要求有用冰沙。
- ***allowobfuscation*** 指定對(duì)象可能會(huì)被混淆侨艾,即使他們被keep保留。所指定對(duì)象可能會(huì)被重命名拓挥,但可能不會(huì)被刪除或者優(yōu)化唠梨。該修飾符只對(duì)實(shí)現(xiàn)異常要求有用。
***
###Shrinking Options *壓縮選項(xiàng)*
壓縮是默認(rèn)開啟的侥啤。壓縮會(huì)刪除沒有使用的類以及類成員当叭,除了由各種“-keep”選項(xiàng)列出的類和它們直接或間接依賴的類茬故。 在每個(gè)優(yōu)化步驟之后都會(huì)進(jìn)行壓縮步驟,因?yàn)橐恍﹥?yōu)化后可能會(huì)出現(xiàn)更多可以刪除的類及類成員
**-dontshrink**
關(guān)閉壓縮
**-printusage** [*filename*]
列出被那些未使用的代碼蚁鳖,并可輸出到指定文件磺芭。僅用于收縮階段
**-whyareyoukeeping** *class_specification*
打印指定的類在壓縮階段為什么會(huì)保留其類、類成員的詳細(xì)信息
***
###Optimization Options *優(yōu)化選項(xiàng)*
優(yōu)化是默認(rèn)情況下啟用的;醉箕。所有方法都在字節(jié)碼級(jí)進(jìn)行優(yōu)化钾腺。
**-dontoptimize**
關(guān)閉優(yōu)化
**-optimizations** *optimization_filter*
指定更精細(xì)級(jí)別的優(yōu)化,僅用于優(yōu)化階段
**-optimizationpasses** *n*
指定優(yōu)化次數(shù)讥裤,默認(rèn)情況下1次放棒。多次可以更進(jìn)一步優(yōu)化代碼,如果在一次優(yōu)化后沒有改進(jìn)則優(yōu)化結(jié)束己英。僅用于優(yōu)化階段
**-assumenosideeffects** *class_specification*
指示沒有任何副作用的類方法哨查。優(yōu)化過程中如果確定這些方法沒有被調(diào)用或者返回值沒有被使用則刪除它們。ProGuard會(huì)分析出庫代碼以外的程序代碼剧辐。如指定System.currentTimeMillis()方法寒亥,任何對(duì)他的空閑調(diào)用將被刪除。僅實(shí)用與優(yōu)化荧关。慎用溉奕!
**-allowaccessmodification**
指示容許修改類和類成員的訪問修飾符,這可以改進(jìn)優(yōu)化結(jié)果忍啤。
**-mergeinterfacesaggressively**
指示容許合并接口加勤,及時(shí)他們的實(shí)現(xiàn)類沒有實(shí)現(xiàn)所有接口方法。這個(gè)可以減少類的總數(shù)來減小輸出的大小同波。僅實(shí)用于優(yōu)化
***
###Obfuscation Options *混淆*
混淆是默認(rèn)開啟的鳄梅。混淆使類和類成員名稱變成短的隨機(jī)名未檩,被各種“-keep”選項(xiàng)保護(hù)的類戴尸、類成員除外。對(duì)調(diào)試有用的內(nèi)部屬性(源文件名稱冤狡,變量名稱孙蒙,行號(hào))將被刪除。
**-dontobfuscate**
關(guān)閉混淆
**-printmapping** [*filename*]
打印舊名稱到重命名的類悲雳、類成員的新名稱的映射關(guān)系挎峦,可輸出到指定文件。
僅實(shí)用于混淆處理
**-applymapping** [*filename*]
指定文件為映射文件合瓢,混淆時(shí)映射文件中列出的類和類成員接收指定的名稱坦胶,文件未提及的類和類成員接收新名稱。
**-obfuscationdictionary** [*filename*]
指定一個(gè)文本文件,其中所有有效字詞都用作混淆字段和方法名稱顿苇。 默認(rèn)情況下峭咒,諸如“a”,“b”等短名稱用作混淆名稱岖圈。 使用模糊字典讹语,您可以指定保留關(guān)鍵字的列表,或具有外來字符的標(biāo)識(shí)符蜂科,例如: 忽略空格顽决,標(biāo)點(diǎn)符號(hào),重復(fù)字和#符號(hào)后的注釋导匣。 注意才菠,模糊字典幾乎不改善混淆。 有些編譯器可以自動(dòng)替換它們贡定,并且通過使用更簡(jiǎn)單的名稱再次混淆赋访,可以很簡(jiǎn)單地撤消該效果。 最有用的是指定類文件中通常已經(jīng)存在的字符串(例如'Code')缓待,從而減少類文件的大小蚓耽。 僅適用于混淆處理。
**-classobfuscationdictionary** [*filename*]
指定一個(gè)文本文件旋炒,其中所有有效詞都用作混淆類名步悠。 與-obfuscationdictionary類似。 僅適用于混淆處理瘫镇。
**-packageobfuscationdictionary** [*filename*]
指定一個(gè)文本文件鼎兽,其中所有有效詞都用作混淆包名稱。與-obfuscationdictionary類似铣除。 僅適用于混淆處理谚咬。
**-overloadaggressively**
深度重載混淆。這個(gè)選項(xiàng)可能會(huì)使參數(shù)和返回類型不同的方法和屬性混淆后獲得同樣的名字尚粘,這個(gè)選項(xiàng)會(huì)使代碼更性褙浴(且不易理解),僅實(shí)用于混淆處理
**-useuniqueclassmembernames**
指定為具有相同名稱的類成員分配相同的混淆名稱背苦,并為具有不同名稱(對(duì)于每個(gè)給定類成員簽名)的類成員分配不同的混淆名稱互捌。 沒有該選項(xiàng),更多的類成員可以映射到相同的短名稱行剂,如'a','b'等钳降。因此選項(xiàng)稍微增加了生成的代碼的大小厚宰,但它確保保存的混淆名稱映射可以始終 在隨后的增量混淆步驟中受到尊重。
**-dontusemixedcaseclassnames**
混淆時(shí)不生成大小寫混合的類名。 默認(rèn)情況下铲觉,混淆的類名稱可以包含大寫字符和小寫字符的混合澈蝙。僅適用于混淆處理。
**-keeppackagenames** [*package_filter*]
指定不混淆給定的包名稱撵幽。*package_filter*過濾器是以逗號(hào)分隔的包名稱列表灯荧。包名稱可以包含 **?**、** * **盐杂、** ** ** 通配符逗载。僅適用于混淆處理。
**-flattenpackagehierarchy** [*package_name*]
將所有重命名后的包移動(dòng)到給定的包中重新打包链烈,如果沒有參數(shù)或者空字符串厉斟,包將被移動(dòng)到根包中,此選項(xiàng)進(jìn)一步混淆包名稱强衡,可以使代碼跟小更不易理解擦秽。僅適用于混淆處理。
**-repackageclasses** [*package_name*]
重新打包所有重命名的類文件漩勤,將它們移動(dòng)到給定包中感挥。 如果包中沒有參數(shù)或一個(gè)空字符串,包被完全刪除越败。 此選項(xiàng)將覆蓋-flattenpackagehierarchy選項(xiàng)触幼。 它可以使處理后的代碼更小,更不容易理解眉尸。 它的已棄用名稱是-defaultpackage域蜗。 僅適用于混淆處理。
**-keepattributes** [*attribute_filter*]
指定要保留的任何可選屬性(注釋...)噪猾。 可以使用一個(gè)或多個(gè)-keepattributes指令指定屬性霉祸。 *attribute_filter*過濾器是以逗號(hào)分隔的屬性名稱列表。如果代碼依賴于注釋袱蜡,則可能需要保留注釋丝蹭。 僅適用于混淆處理。
**-keepparameternames**
指定保留參數(shù)名稱和保留的方法類型坪蚁。 此選項(xiàng)實(shí)際上保留調(diào)試屬性LocalVariableTable和LocalVariableTypeTable的修剪版本奔穿。 它在處理庫時(shí)很有用。 一些IDE可以使用該信息來幫助使用庫的開發(fā)人員敏晤,例如使用工具提示或自動(dòng)完成贱田。僅適用于混淆處理。
**-renamesourcefileattribute** [string]
指定要放在類文件的SourceFile屬性(和SourceDir屬性)中的常量字符串嘴脾。 請(qǐng)注意男摧,該屬性必須以開頭存在蔬墩,因此也必須使用-keepattributes指令明確保留。 例如耗拓,您可能希望使已處理的庫和應(yīng)用程序生成有用的混淆堆棧跟蹤拇颅。僅適用于混淆處理。
**-adaptclassstrings** [*class_filter*]
混淆和類名稱對(duì)應(yīng)的字符串常量乔询,如果沒有filter則匹配與類名稱相對(duì)應(yīng)的所有字符串常量樟插,使用filter則僅匹配與filter匹配的類中的字符串常量。 僅適用于混淆處理竿刁。
**-adaptresourcefilenames** [*file_filter*]
根據(jù)相應(yīng)類文件(如果有)的混淆名稱指定要重命名的資源文件黄锤。 如果沒有過濾器,則重命名與類文件相對(duì)應(yīng)的所有資源文件们妥。 使用過濾器猜扮,僅重命名匹配的文件。僅適用于混淆處理监婶。
**-adaptresourcefilecontents** [*file_filter*]
指定要更新其內(nèi)容的資源文件旅赢。 根據(jù)相應(yīng)類的混淆名稱(如果有)重命名資源文件中提到的任何類名。 如果沒有過濾器惑惶,所有資源文件的內(nèi)容都會(huì)更新煮盼。 使用過濾器,僅更新匹配的文件带污。 資源文件使用平臺(tái)的默認(rèn)字符集進(jìn)行解析和編寫僵控。 您可以通過設(shè)置環(huán)境變量LANG或Java系統(tǒng)屬性file.encoding來更改此默認(rèn)字符集。 僅適用于混淆處理鱼冀。
***
###Preverification Options *預(yù)驗(yàn)證*
預(yù)驗(yàn)證默認(rèn)情況下啟動(dòng)的报破。能提高虛擬機(jī)的加載效率。
**-dontpreverify**
關(guān)閉預(yù)驗(yàn)證
**-microedition**
指定已處理的類文件針對(duì)Java Micro Edition千绪。 然后充易,preverifier將添加適當(dāng)?shù)腟tackMap屬性,這些屬性與Java Standard Edition的默認(rèn)StackMapTable屬性不同荸型。 例如盹靴,如果您正在處理midlet,則需要此選項(xiàng)瑞妇。
***
###General Options *一般選項(xiàng)*
**-verbose**
混淆過程中打印詳細(xì)信息稿静,如果異常終止則打印整個(gè)堆棧信息
**-dontnote** [*class_filter*]
不打印配置類中可能的錯(cuò)誤或遺漏的注釋,如類名稱中的拼寫錯(cuò)誤辕狰,或者可能有用的缺失選項(xiàng)改备。 可選*class_filter*是正則表達(dá)式; ProGuard不打印關(guān)于具有匹配名稱的類的注釋。
**-dontwarn** [*class_filter*]
不對(duì)指定的類蔓倍、包中的不完整的引用發(fā)出警告
**-ignorewarnings**
忽略警告繼續(xù)處理
**-printconfiguration** [*filename*]
打印配置信息绍妨,到指定文件润脸。包括文件和替換的變量
**-dump** [*filename*]
打印類文件內(nèi)部結(jié)構(gòu)到指定文件
***
###<p id='classpath'>Class Paths</p>
*class_paths* 主要用以指示選項(xiàng)(***-injars柬脸、-outjars他去、-libraryjars***)的輸入輸出文件路徑。ProGuard接受類路徑的泛化倒堕。由一系列文件和分隔符組成(在Unix上為***':'***灾测,windows上為***';'***);文件的順序決定著優(yōu)先級(jí)垦巴。
***輸入項(xiàng)可包括:***
- class 文件或者 resource文件媳搪;
- jar 文件, 可包含上述任意文件骤宣;
- war文件秦爆,可包含上述任意文件;
- ear文件憔披, 可包含上述任意文件等限;
- zip文件, 可包含上述任意文件芬膝;
- 包含上面任意文件的目錄結(jié)構(gòu)望门。
直接指定類文件或者資源文件的路徑會(huì)被忽略,類文件可作為jar文件锰霜、war筹误、ear、zip或者目錄結(jié)構(gòu)的一個(gè)部分癣缅。此外厨剪,類文件的路徑在歸檔或目錄中不應(yīng)有任何其他目錄前綴。
***輸出項(xiàng)可包括:***
- jar 文件友存, 包含了所處理的所有class文件或者資源文件祷膳;
- war文件,包含上述任意文件爬立;
- ear文件钾唬, 包含上述任意文件;
- zip文件侠驯, 包含上述任意文件抡秆;
- 包含上面任意文件的目錄結(jié)構(gòu)。
ProGuard 在輸出時(shí)吟策,會(huì)以合理的形式打包輸出結(jié)果儒士,根據(jù)需要重新構(gòu)建輸入文件。將所有類容寫入輸出目錄是ProGuard最便捷的方式檩坚,輸出目錄包含了輸入類容完整的重構(gòu)着撩。包可以是任意復(fù)雜的诅福,可以是處理整個(gè)應(yīng)用程序,zip文件中的包及其文檔拖叙,將再次作為zip文件被處理氓润。
ProGuard容許在文件名中稱使用過濾器,它們能相對(duì)于完整的文件名過濾條一些文件或者其內(nèi)容薯鳍,過濾器位于括號(hào)()之間咖气,他能支持5個(gè)類型以“***;***隔開”:
- 對(duì)所有的zip文件名稱的過濾;
- 對(duì)所有的ear文件名稱的過濾挖滤;
- 對(duì)所有的war文件名稱的過濾崩溪;
- 對(duì)所有的jar文件名稱的過濾;
- 對(duì)于所有的class文件名斩松,資源文件名伶唯。
括號(hào)中的過濾器如果少于5個(gè),則它們將被假設(shè)為最后一個(gè)過濾器惧盹,空的過濾器將被忽視乳幸, 格式如下:
***classpathentry([[[[zipfilter;]earfilter;]warfilter;]jarfilter;]filefilter)***
***“[]”*** 表示其內(nèi)容是可選的。
rt.jar(java/.class,javax/class)
匹配了rt.jar文件中岭参,所有文件夾java反惕、javax下的所有class文件
input.jar(!.gif,images/)
匹配了input.jar中,images文件夾下除.gif格式的所有文件
不同的過濾器可同時(shí)在一個(gè)條目中演侯,它會(huì)被應(yīng)用于所有相應(yīng)的類型姿染;不管它們的嵌套關(guān)系如何他們都是相交的
input.war(lib/.jar,support/jar;.class,.gif)
只包含了lib、support目錄下的jar文件秒际,并且匹配了它其中的所有.class文件和.gif文件
一些例子:
所有輸出類和資源將被合并到一個(gè)jar文件中悬赏。
-injars classes
-injars in1.jar
-injars in2.jar
-injars in3.jar
-outjars out.jar
將classes目錄、in1.jar娄徊、in2.jar闽颇、in3.jar重構(gòu)合并到out.jar文件中
如果想保留輸入的結(jié)構(gòu),則可以輸出到目錄結(jié)構(gòu)(或者 war寄锐、ear兵多、zip)中。
-injars in1.jar
-injars in2.jar
-injars in3.jar
-outjars out
輸入文件能夠保留原來文件名在目錄out中構(gòu)建
通過***分組使用-injars和-outjars***可以靈活的將jars(wars橄仆、ears剩膘、zips 或者 directories)合并到不同的jars(wars、ears盆顾、zips 或者 directories)中:
-injars base_in1.jar
-injars base_in2.jar
-injars base_in3.jar
-outjars base_out.jar
-injars extra_in.jar
-outjars extra_out.jar
base_in*.jar文件會(huì)被合并到base_out.jar文件中怠褐,extra_in.jar被合并到extra_out.jar文件中。
過濾掉了所有images下的所有文件
-injars in.jar(!images/**)
-outjars out.jar
忽略掉java運(yùn)行時(shí)不相關(guān)的類; “<>”表示引用系統(tǒng)變量java home(JAVA_HOME)
-libraryjars <java.home>/lib/rt.jar(java/,javax/)
-injars in.jar
-outjars code_out.jar(**.class)
-outjars resources_out.jar
**.class文件將被輸出到code_out.jar文件中您宪,而所有其他文件將被輸出到resources_out.jar文件中奈懒。
***
###文件名稱(File Names)
ProGuard 接受***絕對(duì)路徑和相對(duì)路徑***作為文件或者路徑名奠涌。相對(duì)路徑規(guī)則為:
- 首先相對(duì)與基礎(chǔ)路徑,如果沒有設(shè)置則:
- 相對(duì)于指定的配置路徑磷杏,如果沒有則:
- 相對(duì)于工作目錄溜畅。
名稱中可包含java 系統(tǒng)配置,用“<>”括號(hào)包裹茴丰。系統(tǒng)配置將自動(dòng)替代它們:
"<java.home>/lib/rt.jar" 將被解釋為 "/usr/local/java/jdk/jre/lib/rt.jar."
"<user.home>" 解釋為用戶的Home目錄
"<user.dir>"解釋為當(dāng)前的工作目錄
**注意:具有空格和括號(hào)的特殊字符名稱必須用單引號(hào)或者雙引號(hào)引用达皿,名稱列表中的每個(gè)文件名必須單獨(dú)引用。在命令行中引號(hào)本身可能需要轉(zhuǎn)義贿肩,以避免shell誤解**
***
###文件過濾符號(hào)說明(File Filters)
>參考 *-adaptresourcefilenames、-adaptresourcefilecontents*
***“file_filter”*** 和一般的Filters一樣龄寞,是可以用逗號(hào)(",")分隔的一個(gè)過路調(diào)的文件列表汰规,只讀取匹配到的文件,支持一下通配符:
**物邑?** 匹配單個(gè)字符溜哮;
**\*** 匹配任意多個(gè)字符,不包括目錄分隔符色解;
****** 匹配任意多個(gè)字符茂嗓,不包括目錄分隔符;
**科阎!** 表示否(取反)述吸。
java/.class,javax/.class //匹配java和javax目錄以及其子目錄下的所有.class文件
-keep class org.codehaus.jackson.* //保持org.codehaus.jackson下面的類文件,不包括其子包里面類文件
-keep class org.codehaus.jackson.//保持org.codehaus.jackson下面所有類文件锣笨,包括其子包里面類文件
!.gif,images/** 匹配images目錄下面所有文件蝌矛,但不包括.gif文件
-injars in.jar(!images/**) //指定輸入jar包,但移除images目錄下面的所有文件
***
###Filter
ProGuard 容許配置的很多選項(xiàng)(文件错英、目錄入撒、類、包椭岩、屬性茅逮、優(yōu)化...等的名稱)使用過濾器∨懈纾可以使用逗號(hào)","分隔献雅。
"foo,bar"匹配foo文件,和所有以bar結(jié)尾的名稱姨伟。
"!foobar,bar 匹配所有bar結(jié)尾名稱惩琉,foobar除外。
***
### Class Specifications(類的書寫規(guī)范模版)
類規(guī)范是一個(gè)類和類成員的書寫模版夺荒。它主要用在 ***-keep瞒渠、-assumenosideeffects***選項(xiàng)后面良蒸。它使得相應(yīng)的選項(xiàng)只適應(yīng)與模版匹配的類和類成員。
規(guī)范看起來類似Java語法伍玖,外加一些通配符嫩痰。下面看一下類規(guī)范格式:
[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname
[extends|implements [@annotationtype] classname]
[{
[@annotationtype] [[!]public|private|protected|static|volatile|transient ...] <fields> |
(fieldtype fieldname);
[@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract|strictfp ...] <methods> |
<init>(argumenttype,...) |
classname(argumenttype,...) |
(returntype methodname(argumenttype,...));
[@annotationtype] [[!]public|private|protected|static ... ] *;
...
}]
######說明:
***"[]“***方括號(hào)表示里面的內(nèi)容是可選的;
***"..."***省略號(hào)表示可以能很多選項(xiàng);
***"|"***豎線劃分了不同的選擇
"()"普通非粗體括號(hào)表示屬于同一組的屬性
- ***class***關(guān)鍵字表示任何類或接口,***interface*** 僅指示接口窍箍,***enum***關(guān)鍵字僅指示枚舉串纺;***interface,enum***前面加一個(gè)***"!"***表示非既是不是接口也不是枚舉。
- 每個(gè)***classname***必須是全名椰棘,如:***java.lang.String纺棺、com.example.ClassName***;同時(shí)***classname***還可以是包含下面一些通配符的正則表達(dá)式:
***?*** 問號(hào)匹配單個(gè)字符,但不能是包名分隔符邪狞;如:***"mypackage.Test?"***祷蝌,能匹配***"mypackage.Test1"、
"mypackage.Test2"***帆卓,但是不能匹配***"mypackage.Test12"***;
***\**** 單個(gè)星號(hào)能匹配任意多個(gè)字符巨朦,但除了包分隔符,如:***"mypackage.\*Test\*"***,能匹配***”mypackage.Test剑令、mypackage.YourTestApplication“***糊啡,但是不能匹配***"mypackage.mysubpackage.MyTest"***; ***"mypackage.\*"***匹配包mypackage下面的類,但不包括它的子包里面的類吁津;
***\*\**** 雙星號(hào)匹配任意多個(gè)字符棚蓄,包括包名的分隔符;如:***"\*\*.Test"***,匹配了所有Test類腺毫,***"mypackage.\*"***匹配了包mypackage下面的所有子類癣疟,包括它的子包的類。
- ***extends 潮酒、implements*** 指示一個(gè)特定的類睛挚,既是表示繼承或者是實(shí)現(xiàn)了指定的類(接口)的類才符合條件。
- ***@*** 指示被注釋類型注釋了的類或類成員急黎。注釋類型與類名一樣被指定扎狱。
- 類成員、方法和java語法差不多勃教,方法參數(shù)就想javadoc一樣淤击,不用包含參數(shù)名稱。成員故源、方法也可以包含一些通配符:
***<init>*** 匹配了構(gòu)造方法污抬;
***<fields>*** 匹配了成員變量;
***<methods>*** 匹配了方法;
***\**** 匹配了任意成員印机、方法矢腻;
上面這些沒有任何返回類型,只有***"<init>"***有參數(shù)列表射赛。
成員變量多柑、方法也可以是包含通配符的正則表達(dá)式¢乖穑可以包含以下通配符:
***?*** 匹配方法中任何單個(gè)字符竣灌;
***\**** 匹配方法中任何多個(gè)字符;
類型可以包含一下通配符
***%*** 匹配方法中的原始類型(***"boolean"秆麸、"int"...***初嘹,不包括***"void"***);
***?*** 匹配類名中的單個(gè)字符蛔屹;
***\**** 匹配類名中的多個(gè)字符削樊,不包括包分隔符;
***\*\**** 匹配類名中的多個(gè)字符兔毒,包括包分隔符;
***\*\*\**** 匹配原始類型甸箱,非原始類型育叁,數(shù)組、非數(shù)組
***\-\-\-*** 匹配任意數(shù)量和類別的參數(shù)芍殖。
注意:***豪嗽?、\*豌骏、\*\**** 不會(huì)匹配原始類型龟梦,只有**\*\*\***可以;如:***"\*\* get\*()"***匹配***“java.lang.Object getObject()”*** 不會(huì)匹配***"float getFloat()"*** 也不匹配***"java.lang.Object[] getObjects()"***;
- 構(gòu)造函數(shù)可以用短名(不含包名)窃躲,或者全名(含包名)计贰;java中構(gòu)造函數(shù)可以有參數(shù),但沒有返回類型蒂窒。
- 可以設(shè)置類躁倒,類成員訪問修飾符(***public,private...***),它們通常幫助限制通配符類和成員洒琢。只能匹配具有指定修飾符的類或者成員秧秉。**"!"**表示非。
容許設(shè)置多個(gè)標(biāo)識(shí)(***"public static"***),但如果它們是沖突的就只能設(shè)置一個(gè)(如***public***和***private***)
ProGuard支持編譯器設(shè)置的一些修飾符***synthetic衰抑、bridge象迎、varargs***;
下面是一些簡(jiǎn)單的列子:
保持了類ClassOneOne里面所有public 修飾的成員和方法
-keepclassmembernames class com.dev.demo.one.ClassOneOne {
public *;
}
保持了ClassOne里面public 修飾的構(gòu)造函數(shù)
-keep class com.dev.demo.ClassOne {
public <init>();
}
保持了類ClassTwoTwo里面public修飾的參數(shù)為int的構(gòu)造函數(shù)
-keep class com.dev.demo.two.ClassTwoTwo {
public <init>(int);
}
保持了類ClassTwoThree 里面public修飾的方法和private修飾的成員變量
-keepclassmember class com.dev.demo.two.ClassTwoThree {
public <methods>;
private <fields>;
}
保持了ClassTwoThree的子類以及里面的成員和方法
-keep class * extends com.dev.demo.two.ClassTwoThree {*;}
保持了前綴為ClassOne的類以及里面的成員和方法
-keepnames class com.dev.demo.one.ClassOne{;}
保持了ClassTwoTwo的內(nèi)部類ClassTwoTwoInner里面的成員和方法
-keep class com.dev.demo.two.ClassTwoTwo$ClassTwoTwoInner{*;}