啟用應用程式最佳化功能時,R8 會使用預設設定執行大量最佳化作業,盡可能提升效能。R8 會大幅修改程式碼,包括重新命名、移動及移除類別、欄位和方法。如果發現這些修改會導致錯誤,您需要指定 R8 不應修改的程式碼部分,方法是在保留規則中宣告這些部分。
需要保留規則的常見情況
R8 會找出並保留程式碼中的所有直接呼叫。不過,R8 無法查看間接程式碼用法,因此可能會移除應用程式需要的程式碼,導致當機。使用保留規則,告知 R8 保留這類間接使用的程式碼。以下是幾種常見情況,您可能需要保留規則:
- 透過反射存取的程式碼:R8 無法識別類別、欄位或方法是否透過反射存取。舉例來說,R8 無法使用
Class.getDeclaredMethod()依名稱查閱方法,也無法使用Class.getAnnotation()擷取註解。在這些情況下,R8 可能會重新命名這些方法和註解,或完全移除,導致在執行階段發生ClassNotFoundException或NoSuchMethodException。 - 透過 Java Native Interface (JNI) 呼叫的程式碼:當原生 (C 或 C++) 程式碼呼叫 Java 或 Kotlin 方法,或是 Java 或 Kotlin 程式碼透過 JNI 呼叫 C++ 程式碼時,系統會根據方法名稱的動態字串查閱結果進行呼叫。R8 無法查看以動態字串為基礎的方法呼叫,因此最佳化作業可能會導致程式碼中斷。
這份清單並未列出所有需要保留規則的情境,但已涵蓋大部分可能需要保留規則的情況。
如何為應用程式新增保留規則
保留規則的設定取決於您使用的 AGP 版本。
大型應用程式通常會在多個程式庫模組中包含程式碼。在這種情況下,最好將保留規則放在特定程式庫模組中,與適用的程式碼並列。為程式庫維護保留規則時,最主要的差異在於如何在程式庫模組的 build.gradle.kts (或 build.gradle) 檔案中宣告這些規則。詳情請參閱「程式庫作者的最佳化做法」。
適用於 AGP 9.3 以上版本
在 src/<variant>/keepRules 目錄中,將規則新增至以 .keep 為後置字元的檔案。例如:src/main/keepRules/custom-rules.keep。請注意,針對 AGP 9.3 以上版本使用更新的 DSL 時,系統會同時啟用程式碼和資源最佳化功能,且「不」需要您明確定義預設的 Android 保留規則檔案 (proguard-android-optimize.txt),因為系統預設會納入該檔案,除非您明確省略。
Kotlin
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
}
Groovy
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
}
}
}
}
省略預設 Android 平台保留規則 (進階)
AGP 提供一組預設的 Android 平台規則。如要從專案設定中省略這些規則,並自行管理所有保留規則,請將 optimization.keepRules.includeDefault 設為 false。
Kotlin
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
keepRules {
includeDefault = false // The file with optimization
// rules for the Android platform is included by
// default. To omit this file, set this option to false.
}
}
}
}
}
Groovy
android {
buildTypes {
release {
optimization {
enable = true // Enables code and resource optimizations.
keepRules {
includeDefault = false // The file with optimization
// rules for the Android platform is included by
// default. To omit this file, set this option to false.
}
}
}
}
}
適用於 AGP 9.3 以下版本的舊版 DSL
在應用程式模組根目錄的 proguard-rules.pro 檔案中新增規則 (檔案可能已存在,如果沒有,請建立檔案)。如要套用檔案中的規則,您必須在模組層級 build.gradle.kts (或 build.gradle) 檔案中宣告該檔案。
根據預設,建構檔案也會包含 proguard-android-optimize.txt 檔案。這個檔案包含大多數 Android 專案都需要的規則,因此請保留在建構檔案中。這個檔案是以「proguard-common.txt」檔案為基礎,並與該檔案共用內容。
舊版 DSL (Kotlin)
android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
// Default file with default optimization rules.
getDefaultProguardFile("proguard-android-optimize.txt"),
...
)
}
}
}
舊版 DSL (Groovy)
android {
buildTypes {
release {
minifyEnabled = true
shrinkResources = true
// Default file with default optimization rules.
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
...
}
}
}
新增保留規則
新增保留規則時,您可以加入全域選項,以及定義自己的保留規則。
全域選項:全域選項是影響 R8 如何處理整個程式碼集的通用指令。詳情請參閱「全域選項」。
保留規則:請仔細設計保留規則,確保您在盡量最佳化程式碼的同時,不會不慎破壞應用程式。如要瞭解如何編寫保留規則,請參閱「新增保留規則」。
程式庫作者的保留規則
瞭解保留規則的語法和全域選項後,請參閱「程式庫作者的最佳化做法」,進一步瞭解詳情。