R8 提供全域選項,可修改整個應用程式的 R8 最佳化作業,或影響每項保留規則。這些選項會與保留規則一起維護在 proguard-rules.pro 檔案中。這些全域選項有些可設定額外最佳化,有些則可關閉最佳化的特定層面。
其他最佳化作業的全域選項
下列全域選項可啟用額外最佳化功能:
-repackageclasses [<optional-package-name>]:將類別重新封裝成單一套件,以縮減應用程式大小。如果您未提供選用的套件名稱,類別會移至未命名的預設套件。建議您為應用程式使用這項設定,因為這樣做會從類別名稱中省略套件前置字元,進而縮減 DEX 檔案大小。-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 |
這項屬性會儲存適用於型別用途的註解,而不只是宣告。這項屬性在執行階段不會顯示。 應用程式開發人員不應保留這項屬性。對程式庫作者而言,這個屬性與消費者保留規則無關,但建構程式庫時經常會用到。如要瞭解如何最佳化程式庫,請參閱「程式庫作者的最佳化做法」。 |