使用規則排解最佳化問題

除了保留規則其他保留規則類型全域選項外,您也可以使用特定規則來排解最佳化問題。

-checkdiscard

-checkdiscard 規則可讓您檢查 R8 是否已成功捨棄您預期會移除的類別或其成員。如果指定的類別或成員未遭捨棄,建構作業就會失敗。

-checkdiscard 的語法如下:


-checkdiscard <class_specification>

在下列範例中,如果保留 userId 欄位或 com.example.models.User 類別中的 setLabel() 方法,建構作業就會失敗:

-checkdiscard class com.example.models.User{
  private java.lang.String userId;
  public void setLabel(java.lang.String);
}

如果類別的方法內嵌至其他類別,應用程式中可能仍會存在該類別的程式碼。如要確保程式碼已完全移除,而不只是內嵌,請新增相應規則,禁止 R8 對目標類別執行最佳化作業,方法是合併 -checkdiscard-keep,allowshrinking 規則。這會禁止類別合併和內嵌等最佳化作業。如果 -checkdiscard 規則通過,則最佳化應用程式中不會有任何相符類別的內容。

請參考下列範例:

# Either keep or remove the class, don't rename or otherwise optimize it
-keep,allowshrinking class com.example.foo { *; }

# Verify that the class and all of its fields and methods are removed.
-checkdiscard class com.example.foo

-whyareyoukeeping

使用 -whyareyoukeeping 規則判斷 R8 在應用程式建構作業中保留特定類別、欄位或方法的原因。項目保留的原因可能不只一個,但這項規則只會提供從保留項目到該項目的最短路徑。如果從程式碼中移除這個路徑,系統可能仍會保留該項目,但原因不同。

可能原因如下:

  • 保留規則:保留規則可能來自應用程式、使用的程式庫,或是 AAPT (Android 資產封裝工具) 產生的規則。

  • 保留程式碼或資源的遞移參照:如果 R8 保留程式碼或 XML (例如版面配置),則會保留靜態參照的任何項目。

語法如下:


-whyareyoukeeping <class_specification>

例如:

-whyareyoukeeping class com.example.foo.MainActivity {
  private void setLabel(...);
}

輸出內容會列印到主控台。

如果沒有任何規則保留 setLabel(),輸出內容如下:

com.example.foo.MainActivity
|- is referenced in keep rule:
|  /app/build/intermediates/aapt_proguard_file/release/processReleaseResources/aapt_rules.txt:4:1
Nothing is keeping void com.example.foo.MainActivity.setLabel()

如果您有以 setLabel() 為目標的保留規則,輸出內容會類似於下列內容:

com.example.foo.MainActivity
|- is referenced in keep rule:
| /app/proguard-rules.pro:23:1
void com.example.foo.MainActivity.setLabel()
|- is referenced in keep rule:
|  /app/proguard-rules.pro:23:1