新增全域選項

R8 提供全域選項,可修改整個應用程式的 R8 最佳化作業,或影響每項保留規則。這些選項會與保留規則一起維護在 proguard-rules.pro 檔案中。部分全域選項可設定額外最佳化功能,其他選項則可關閉最佳化的特定層面。

全域選項,可進一步最佳化

下列全域選項可啟用額外最佳化功能:

  • -repackageclasses [<optional-package-name>]:將類別重新封裝到單一指定套件中,進一步縮減應用程式大小。如果您未提供選用的套件名稱,系統會將類別移至空白的預設套件。這是應用程式的建議設定。
  • -allowaccessmodification:允許 R8 變更 (通常是擴大) 類別、欄位和方法的瀏覽權限,以執行更廣泛的最佳化。使用 proguard-android-optimize.txt 時會啟用。自 Android Gradle 外掛程式 (AGP) 8.2 起,如果您在完整模式下使用 R8,這就是預設設定。

以下是啟用額外最佳化的設定範例:

-repackageclasses
-allowaccessmodification

限制最佳化的全域選項

您可以透過下列全域選項關閉應用程式最佳化的特定功能,這在調整保留規則或首次啟用 R8 時很有幫助。

  • -dontoptimize:防止程式碼最佳化,例如方法內嵌。這個選項可用於開發期間,但不應在正式版建構中使用。
  • -dontshrink:防止移除未參照的程式碼和程式碼最佳化。這個選項可用於開發期間,但不應在正式版建構中使用。
  • -dontobfuscate:防止縮短類別和方法的名稱。在偵錯期間關閉混淆處理功能,有助於輕鬆解讀堆疊追蹤記錄。這個選項可用於開發期間,但不應在正式版建構中使用。
  • -keepattributes <attributes>:接受以半形逗號分隔的屬性清單,這些屬性應保留。如果沒有使用預設的 proguard-android-optimize.txt,R8 會移除所有屬性,包括 RuntimeVisibleAnnotationsSignature,但如果需要保留這些屬性 (例如用於反射),這項功能就很有幫助。如需可指定的屬性清單,請參閱「保留屬性」。

保留屬性

屬性是附加至程式碼不同部分的額外資訊。屬性會儲存來自程式碼的註解和一般簽章等資訊。

某些反射作業需要保留特定屬性,才能順利執行。例如:

  • 使用 getEnclosingMethod()getDeclaredClasses() 存取內部或外部類別結構時,需要 EnclosingMethodInnerClasses 屬性。
  • 使用 getTypeParameters() 存取泛型簽章時,需要 Signature 屬性。
  • 使用 getAnnotation() 存取註解時,需要 RuntimeVisibleAnnotations 屬性。

常見必要屬性

使用預設 ProGuard 檔案 (proguard-android-optimize.txtproguard-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 這項屬性會儲存適用於型別用途的註解,而不只是宣告。這項屬性在執行階段不會顯示。

應用程式開發人員不應保留這項屬性。對程式庫作者而言,這個屬性與消費者保留規則無關,但建構程式庫時經常會用到。如要瞭解如何最佳化程式庫,請參閱「程式庫作者的最佳化做法」。