除了保留規則、其他保留規則類型和全域選項外,您也可以使用特定規則來排解最佳化問題。
-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