R8 提供全域選項,可修改整個應用程式的 R8 最佳化作業,或影響每項保留規則。這些選項會連同保留規則,一併保留在 proguard-rules.pro 檔案中。其中幾項全域選項可設定額外最佳化功能,其他選項則會關閉最佳化的特定部分。
R8 也會接受 (但會忽略) 從 ProGuard 沿用的一些舊版選項。詳情請參閱「移除舊版 ProGuard 選項」。
全域選項,可進一步最佳化
下列全域選項可啟用額外最佳化功能:
-repackageclasses [<optional-package-name>]:將類別重新封裝成單一套件,以縮減應用程式大小。如未提供選用的套件名稱,類別會移至未命名的 (預設) 套件。建議您為應用程式使用這項設定,因為這樣做會從類別名稱中省略套件前置字元,進而縮減 DEX 檔案大小。自 Android Gradle 外掛程式 (AGP) 9.1 起,這是應用程式的預設設定。如要停用這項最佳化功能,請使用-dontrepackage。-allowaccessmodification:允許 R8 變更 (通常是擴大) 類別、欄位和方法的瀏覽權限,以執行更廣泛的最佳化。使用proguard-android-optimize.txt時會啟用。自 Android Gradle 外掛程式 (AGP) 8.2 起,如果您使用 R8 啟用完整最佳化,這就是預設設定。-processkotlinnullchecks [level]:讓 R8 變更 Kotlin Intrinsics 空值檢查,只移除錯誤訊息或完全移除明確的空值檢查。level值 (由弱到強) 的影響如下:keep不會變更檢查。remove_message會將每個檢查方法呼叫重新編寫為對呼叫第一個引數的getClass()呼叫 (有效保留空值檢查,但不含任何訊息)。remove會完全移除檢查。
根據預設,R8 會使用
remove_message。任何-processkotlinnullchecks的規格都會覆寫該規格。如果多次指定,系統會使用最強的值。AGP 9.0.0 以上版本支援
-processkotlinnullchecks。
以下是啟用額外最佳化的設定範例:
-repackageclasses
-allowaccessmodification
限制最佳化的全域選項
您可以透過下列全域選項關閉應用程式最佳化的特定功能,這在調整保留規則或首次啟用 R8 時很有幫助。
-dontoptimize:防止程式碼最佳化,例如方法內嵌。這個選項可用於開發期間,但不應在正式版中使用。-dontshrink:防止移除未參照的程式碼和程式碼最佳化。這個選項可用於開發期間,但不應在正式版建構中使用。-dontobfuscate:防止縮短類別和方法名稱。偵錯時,關閉混淆處理功能特別有幫助,因為這樣比較容易解讀堆疊追蹤。這個選項可用於開發期間,但不應在正式版中使用。-keepattributes <attributes>:接受以半形逗號分隔的屬性清單,這些屬性應保留。如果「不是」使用預設的proguard-android-optimize.txt,R8 會移除所有屬性,包括RuntimeVisibleAnnotations和Signature,但如果需要這些屬性 (例如用於反射),保留這些屬性會很有幫助。如需可指定的屬性清單,請參閱「保留屬性」。
保留屬性
屬性是附加至程式碼不同部分的額外資訊。屬性會儲存來自程式碼的註解和一般簽章等資訊。
某些反射作業需要保留特定屬性,才能順利執行。例如:
- 使用
getEnclosingMethod()或getDeclaredClasses()存取內部或外部類別結構時,需要EnclosingMethod和InnerClasses屬性。 - 使用
getTypeParameters()存取泛型簽章時,需要Signature屬性。 使用
getAnnotation()存取註解時,需要RuntimeVisibleAnnotations屬性。
常見的必要屬性
使用預設 ProGuard 檔案 (proguard-android-optimize.txt 或 proguard-android.txt) 時,Android Gradle 外掛程式 (AGP) 會保留下列屬性。請注意,部分屬性需要較新版本的 AGP:
| 屬性 | 說明 |
|---|---|
AnnotationDefault |
這項屬性位於註解類型本身,並儲存註解元素的預設值。 注意:自 AGP 7.1 起,這項屬性預設會保留,只有在使用舊版 AGP 的應用程式中,才需要明確保留。 |
EnclosingMethod |
這項屬性會出現在非本機或匿名類別的內部類別中。這個屬性會識別直接包含類別的方法或初始值設定器。 |
InnerClasses |
這項屬性會記錄在另一個類別中定義的巢狀類別 (內部類別、靜態巢狀類別、本機類別和匿名類別) 相關資訊。 |
LineNumberTable |
這項屬性會將位元碼指令對應至原始來源檔案中的對應行號。 注意:自 Android Gradle 外掛程式 (AGP) 8.6 起,系統預設會保留這個屬性,只有使用舊版 AGP 的應用程式才需要明確保留。 |
RuntimeVisibleAnnotations |
這項屬性會儲存註解,這些註解在執行階段可透過反射機制顯示。 通常,如果註解是在執行階段使用,應用程式和程式庫消費者規則只需要 *Annotation 屬性中的這個註解。 |
RuntimeVisibleParameterAnnotations |
這個屬性會儲存註解,這些註解會在方法參數上反映,並在執行階段顯示。 |
RuntimeVisibleTypeAnnotations |
這項屬性會儲存適用於型別用途的註解,而不只是宣告。這項屬性會在執行階段顯示。 |
Signature |
這項屬性會儲存類別、方法和欄位的一般類型簽章,特別是使用泛型 (例如 List<String>) 時。 |
SourceFile |
這個屬性會儲存編譯類別的來源檔案名稱 (.kt 或 .java 檔案)。偵錯工具主要會使用這項資訊,在逐步執行已編譯的 Java 程式碼時,顯示原始程式碼行。協助開發人員追蹤執行作業,回到他們編寫的程式碼。注意:自 AGP 8.2 起,系統預設會保留這個屬性,只有使用舊版 AGP 的應用程式才需要明確保留。 |
對於使用 proguard-android-optimize.txt 的應用程式,在大多數情況下,AGP 定義的保留規則就已足夠。不過,如果您要為程式庫編寫程式碼,即使這些屬性已定義於這個清單中,您仍應在程式庫的消費者保留規則中指定所有必要屬性。這樣一來,即使開發人員決定不加入 proguard-android-optimize.txt,您的程式庫也能維持穩定。
其他保留屬性
您可以指定要保留的其他屬性,但對於絕大多數的反射或 JNI 存取情境而言,這些屬性並非必要。不過,最佳化程式庫時,您可能仍會經常使用其中一些函式。
| 屬性 | 說明 |
|---|---|
MethodParameters |
這項屬性提供方法參數的相關資訊,特別是參數名稱和存取權標記。 |
Exceptions |
這項屬性會列出方法宣告要擲回的已檢查例外狀況。 這項屬性通常不適用於應用程式。對於程式庫作者而言,這通常不會用於消費者保留規則,但建構程式庫時經常會用到。如要瞭解如何最佳化程式庫,請參閱「程式庫作者的最佳化做法」。 |
RuntimeInvisibleAnnotations |
這項屬性會儲存在類別、欄位或方法中,但無法在執行階段透過反射機制查看的註解。 應用程式開發人員不應保留這項屬性。對程式庫作者而言,這個屬性與消費者保留規則無關,但建構程式庫時經常會用到。如要瞭解如何最佳化程式庫,請參閱「程式庫作者的最佳化做法」。 |
RuntimeInvisibleParameterAnnotations |
這個屬性會儲存方法參數在執行階段無法透過反射看到的註解。 應用程式開發人員不應保留這項屬性。對程式庫作者而言,這個屬性與消費者保留規則無關,但建構程式庫時經常會用到。如要瞭解如何最佳化程式庫,請參閱「程式庫作者的最佳化做法」。 |
RuntimeInvisibleTypeAnnotations |
這項屬性會儲存適用於型別用途的註解,而不只是宣告。這項屬性在執行階段不會顯示。 應用程式開發人員不應保留這項屬性。對程式庫作者而言,這個屬性與消費者保留規則無關,但建構程式庫時經常會用到。如要瞭解如何最佳化程式庫,請參閱「程式庫作者的最佳化做法」。 |
移除舊版 ProGuard 選項
R8 會接受部分僅在 ProGuard 中生效的選項,但會忽略這些選項。這些選項通常會保留在從 ProGuard 遷移或從舊專案複製的設定中。由於這些註解不會影響 R8 輸出內容,請從 proguard-rules.pro 檔案中移除註解,方便您瞭解及維護設定。
R8 會忽略下列選項,且不會回報警告:
-adaptkotlinmetadata-android-dontpreverify-dontskipnonpubliclibraryclasses-dontskipnonpubliclibraryclassmembers-dontusemixedcaseclassnames-forceprocessing-mergeinterfacesaggressively-optimizationpasses-optimizations-overloadaggressively-target-verbose
R8 會忽略下列選項,並在建構期間回報警告:
-addconfigurationdebugging(AGP 9.0 已移除這項支援)-assumenoescapingparameters-assumenoexternalreturnvalues-assumenoexternalsideeffects-dump-useuniqueclassmembernames
R8 不支援 -skipnonpubliclibraryclasses,如果設定包含這項元素,就會回報錯誤。