ベスト プラクティスに従う

キープルールを使用する際は、アプリの動作を維持しながらメリットを享受できるよう、適切なレベルの具体性を確保することが重要です。保持ルールの適切なパターンと避けるべき事項については、以降のセクションをご覧ください。

保持ルールの適切なパターン

明確に定義された保持ルールは、可能な限り具体的であり、次のパターンに準拠しています。

  • クラス仕様では、次の例に示すように、可能な限り常に特定のクラス、ベースクラス、またはアノテーション付きクラスを指定します。

    -keepclassmembers class com.example.MyClass {
      void someSpecificMethod();
    }
    
    -keepclassmembers ** extends com.example.MyBaseClass {
      void someSpecificMethod();
    }
    
    -keepclassmembers @com.example.MyAnnotation class ** {
      void someSpecificMethod();
    }
    
  • 可能な場合は、ソースコードにアノテーションを使用し、キープルールのターゲットをそのアノテーションに直接設定します。これにより、コードとそれを保持するルール間の明確で明示的なリンクが作成され、構成がより堅牢になり、理解しやすくなり、コードの変更時に破損しにくくなります。

    たとえば、次のスニペットは、MyClass クラスと @com.example.DisplayComponent アノテーションが付いた他のクラスを保持する方法を示しています。

    // In the source code
    @com.example.DisplayComponent
    class MyClass { /* ... */ }
    
    // In the keep rules
    -keep @com.example.DisplayComponent class * {*;}
    

    コード部分が保持される理由について意味のあるコンテキストを提供するように、アノテーションに名前を付けることをおすすめします。たとえば、表示コンポーネントで一部を保持する必要があるアプリには @DisplayComponent を使用します。

  • 可能であれば、メンバー仕様を宣言し、アプリの機能維持に必要なクラスの部分のみを参照する必要があります。厳密に必要でない限り、オプションのメンバー スコープを { *; } として定義して、ルールをクラス全体に適用しないことをおすすめします。

    -keepclassmembers com.example.MyClass {
      void someSpecificMethod();
      void @com.example.MyAnnotation *;
    }
    
  • repackageclasses グローバル オプションを使用する場合は、省略可能なパッケージ名を指定しないでください。これにより、再パッケージ化されたクラス名でパッケージ プレフィックスが省略されるため、DEX ファイルのサイズが小さくなります。

  • リフレクションによってアクセスされるすべてのアイテムの保持ルールを維持します。明示的な keep ルールがなくても、R8 によってこのようなアイテムが保持される場合でも、実際のルールを維持することが重要です。これは、今後のコード変更によって R8 がこれらのアイテムを保持しなくなる可能性があるためです。

これらのガイドラインに準拠できない場合は、保持する必要があるコードを専用のパッケージに一時的に分離し、そのパッケージに保持ルールを適用できます。ただし、これは長期的な解決策ではありません。詳細については、最適化を段階的に導入するをご覧ください。パッケージに保持ルールを使用するには、次の例に示すように保持ルールを定義します。

-keepclassmembers class com.example.pkg.** { *; }

非推奨事項

保持ルールの構文には多くのオプションがありますが、測定可能な持続可能なパフォーマンス上のメリットを得るには、次のオプションを使用しないことをおすすめします。

  • -keep class com.example.pkg.** { *; } long-term などのパッケージ全体の保持ルールは使用しないでください。R8 を構成する際に問題が発生した場合、一時的に使用して問題を回避できます。詳細については、最適化の範囲を制限するをご覧ください。通常、ワイルドカードには注意が必要です。必要なコードのみを保持していることを確認してください。
  • 可能な限り、使用時にキープルールのコピーと貼り付けを提案するライブラリ(特にパッケージ全体のキープルール)は避けてください。Android で適切に動作するように設計されたライブラリは、可能な限りリフレクションを避け、必要に応じてコンシューマーの保持ルールを埋め込む必要があります。
  • 反転演算子 ! を保持ルールで使用しないでください。アプリケーション内のほぼすべてのクラスにルールが誤って適用される可能性があります。

これらのルールに従えない場合は、オープン エンドのリフレクションを多用している可能性があるため、リフレクションを避けるか、リフレクションを使用するライブラリを避ける必要があります(Gson のケーススタディを参照)。