保持ルールについて

デフォルト設定でアプリの最適化を有効にすると、R8 はパフォーマンスのメリットを最大限に高めるために、広範な最適化を実行します。R8 は、クラス、フィールド、メソッドの名前の変更、移動、削除など、コードに大幅な変更を加えます。これらの変更によってエラーが発生する場合は、keep ルールで宣言して、R8 が変更すべきでないコードの部分を指定する必要があります。

keep ルールが必要な一般的なシナリオ

R8 は、コード内のすべての直接呼び出しを特定して保持します。ただし、R8 は間接的なコードの使用を認識できないため、アプリに必要なコードが削除されてクラッシュが発生する可能性があります。keep ルールを使用して、間接的に使用されるコードを保持するように R8 に指示します。keep ルールが必要になる一般的な状況は次のとおりです。

  • リフレクションによってアクセスされるコード: R8 は、リフレクションを使用してクラス、フィールド、メソッドにアクセスするタイミングを特定できません。たとえば、R8 は Class.getDeclaredMethod() を使用して名前で検索されたメソッドや、Class.getAnnotation() で取得されたアノテーションを特定できません。このような場合、R8 はこれらのメソッドとアノテーションの名前を変更するか、完全に削除する可能性があるため、実行時に ClassNotFoundException または NoSuchMethodException が発生します。
  • Java Native Interface(JNI)から呼び出されるコード: ネイティブ(C または C++)コードが Java または Kotlin メソッドを呼び出す場合、または Java または Kotlin コードが JNI を使用して C++ コードを呼び出す場合、呼び出しはメソッド名の動的文字列検索に基づきます。R8 は動的文字列ベースのメソッド呼び出しを認識できないため、最適化によってコードが破損する可能性があります。

これは keep ルールが必要なシナリオの完全なリストではありませんが、これらのシナリオは keep ルールが必要になる可能性のあるほとんどのケースを網羅しています。

アプリに  keep  ルールを追加する方法

keep ルールの構成は、使用する AGP のバージョンによって異なります。

大規模なアプリでは、通常、複数のライブラリ モジュールにコードが含まれています。このような場合は、特定のライブラリ モジュール内で、適用されるコードの横に keep ルールを配置する方が望ましいことがよくあります。ライブラリの keep ルールの維持における重要な違いは、ライブラリ モジュールの build.gradle.kts(または build.gradle)ファイル内でこれらのルールを宣言する方法にあります。詳しくは、ライブラリ作成者向けの最適化をご覧ください。

AGP バージョン 9.3 以降の場合

ルールを src/<variant>/keepRules ディレクトリに .keep という接尾辞の付いたファイルに追加します。例: src/main/keepRules/custom-rules.keep。AGP 9.3 以降の更新された DSL を使用すると、コードとリソースの両方の最適化が可能になります。デフォルトの Android keep ルール ファイル (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 プラットフォーム keep ルールを省略する(詳細)

AGP には、デフォルトの Android プラットフォーム ルールが用意されています。プロジェクトの構成からこれらのルールを省略し、すべての keep ルールを自分で管理するには、optimization.keepRules.includeDefaultfalse に設定します。

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')
            ...
        }
    }
}

keep  ルールを追加する

keep ルールを追加する際は、グローバル オプションを含めることも、独自の keep ルールを定義することもできます。

  • グローバル オプション: グローバル オプションは、R8 がコードベース全体でどのように動作するかに影響する一般的なディレクティブです。詳しくは、グローバル オプションをご覧ください。

  • keep  ルール: keep  ルールは、アプリを誤って破損させることなくコードの最適化を最大限に高める適切なバランスを確保するために、慎重に設計する必要があります。keep  ルールの作成方法については、keep  ルールを追加するをご覧ください。

ライブラリ作成者向けの keep ルール

グローバル オプションと keep ルールの構文について学習したら、ライブラリ作成者向けの最適化で詳細を確認してください。