關於保留規則

啟用應用程式最佳化功能時,R8 會使用預設設定執行大量最佳化作業,盡可能提升效能。R8 會大幅修改程式碼,包括重新命名、移動及移除類別、欄位和方法。如果發現這些修改會導致錯誤,您需要指定 R8 不應修改的程式碼部分,方法是在保留規則中宣告這些部分。

需要保留規則的常見情況

R8 會找出並保留程式碼中的所有直接呼叫。不過,R8 無法查看間接程式碼用法,因此可能會移除應用程式需要的程式碼,導致當機。使用保留規則,告知 R8 保留這類間接使用的程式碼。以下是幾種常見情況,您可能需要保留規則:

  • 透過反射存取的程式碼:R8 無法識別類別、欄位或方法是否透過反射存取。舉例來說,R8 無法使用 Class.getDeclaredMethod() 依名稱查閱方法,也無法使用 Class.getAnnotation() 擷取註解。在這些情況下,R8 可能會重新命名這些方法和註解,或完全移除,導致在執行階段發生 ClassNotFoundExceptionNoSuchMethodException
  • 透過 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 如何處理整個程式碼集的通用指令。詳情請參閱「全域選項」。

  • 保留規則:請仔細設計保留規則,確保您在盡量最佳化程式碼的同時,不會不慎破壞應用程式。如要瞭解如何編寫保留規則,請參閱「新增保留規則」。

程式庫作者的保留規則

瞭解保留規則的語法和全域選項後,請參閱「程式庫作者的最佳化做法」,進一步瞭解詳情。