最新の Android 開発では、小さく、高速で、安全なアプリケーションをリリースすることがユーザーの基本的な期待となっています。これを実現するための Android ビルドシステムの主要ツールは、R8 最適化ツールです。これは、圧縮のためのデッドコードとリソースの削除、コードの名前変更または最小化、アプリの最適化を処理するコンパイラです。
R8 を有効にすることは、アプリをリリースに向けて準備するうえで重要なステップですが、デベロッパーが「Keep ルール」の形式でガイダンスを提供する必要があります。
この記事を読んだら、YouTube で公開されている Performance Spotlight Week の動画で、R8 最適化ツールの有効化、デバッグ、トラブルシューティングについてご確認ください。
Keep ルールが必要な理由
Keep ルールを記述する必要があるのは、R8 が静的解析ツールであるのに対し、Android アプリは多くの場合、リフレクションや JNI(Java Native Interface)を使用したネイティブ コードとの呼び出しなど、動的な実行パターンに依存しているという根本的な矛盾があるためです。
R8 は、直接呼び出しを分析して、使用されているコードのグラフを構築します。コードが動的にアクセスされる場合、R8 の静的解析ではそれを予測できず、そのコードが 未使用 であると識別して削除してしまうため、ランタイム クラッシュが発生します。
Keep ルール は、R8 コンパイラに対する明示的な指示であり、「この特定のクラス、メソッド、またはフィールドは、ランタイム時に動的にアクセスされるエントリ ポイントです。直接参照が見つからない場合でも、保持する必要があります」と伝えます。
Keep ルールの詳細については、公式ガイドをご覧ください。
Keep ルールを記述する場所
アプリケーションのカスタム Keep ルールは、テキスト ファイルに記述します。慣例により、このファイルは proguard-rules.pro という名前で、アプリまたはライブラリ モジュールのルートに配置されます。このファイルは、モジュールの build.gradle.kts ファイルの release ビルドタイプで指定します。
release {
isShrinkResources = true
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}正しいデフォルト ファイルを使用する
getDefaultProguardFile メソッドは、Android SDK によって提供されるデフォルトのルールセットをインポートします。間違ったファイルを使用すると、アプリが最適化されない可能性があります。proguard-android-optimize.txt を使用してください。このファイルは、標準の Android コンポーネントのデフォルトの Keep ルールを提供し、and R8 のコード最適化を有効にします。古い proguard-android.txt は Keep ルールのみを提供し、R8 の最適化を 有効にしません。
これは深刻なパフォーマンスの問題であるため、Android Studio Narwhal 3 Feature Drop 以降では、間違ったファイルを使用しているデベロッパーに警告が表示されるようになります。また、Android Gradle プラグイン バージョン 9.0 以降では、古い proguard-android.txt ファイルはサポートされなくなります。最適化されたバージョンにアップグレードしてください。
Keep ルールの記述方法
Keep ルールは、次の 3 つの主要な部分で構成されます。
- -keep や
-keep-keepclassmembers-keepclassmembersなどの**オプション** allowshrinkingなどの省略可能な修飾子- 一致させるコードを定義するクラス仕様
完全な構文と例については、Keep ルールを追加する手順をご覧ください。
Keep ルールのアンチパターン
ベスト プラクティスだけでなく、アンチパターンについても知っておくことが重要です。これらのアンチパターンは、誤解やトラブルシューティングのショートカットから発生することが多く、本番環境のビルドのパフォーマンスに壊滅的な影響を与える可能性があります。
グローバル オプション
これらのフラグはグローバル トグルであり、リリースビルドでは絶対に使用しないでください 。問題の切り分けのための一時的なデバッグにのみ使用します。
-dontotptimize を使用すると、R8 のパフォーマンス最適化が無効になり、アプリの速度が低下します。
-dontobfuscate を使用すると、すべての名前変更が無効になり、-dontshrink を使用すると、デッドコードの削除が無効になります。どちらのグローバル ルールもアプリのサイズを大きくします。
パフォーマンスの高いアプリのユーザー エクスペリエンスを実現するため、可能な限り本番環境でこれらのグローバル フラグを使用しないようにしてください。
制限が過度に緩い Keep ルール
R8 のメリットを無効にする最も簡単な方法は、制限が過度に緩い Keep ルールを記述する ことです。次のような Keep ルールは、このパッケージまたはそのサブパッケージのすべてのクラスを圧縮、難読化、最適化しないように R8 最適化ツールに指示します。これにより、そのパッケージ全体の R8 のメリットが完全に失われます。代わりに、制限が厳しく具体的な Keep ルールを記述してください。
-keep class com.example.package.** { *;} // WIDE KEEP RULES CAUSE PROBLEMS反転演算子(!)
反転演算子(!)は、ルールからパッケージを除外する強力な方法のように思えますが、そう単純ではありません。例を見てみましょう。
-keep class !com.example.my_package.** { *; } // USE WITH CAUTIONこのルールは「 のクラスを保持しないcom.example.package」という意味だと思われるかもしれませんが、実際には「アプリケーション全体のすべてのクラス、メソッド、プロパティ com.example.packageにないものを保持する」という意味になります。驚いた場合は、R8 構成で否定がないか確認してください。
Android コンポーネントの冗長なルール
もう 1 つのよくある間違いは、アプリの Activities、Services、BroadcastReceivers の Keep ルールを手動で追加することです。これは不要 です。デフォルトの proguard-android-optimize.txt ファイルには、これらの標準の Android コンポーネントがすぐに動作するための関連ルールがすでに含まれています。
また、多くのライブラリには独自の Keep ルールが用意されています。そのため、これらのルールを自分で記述する必要はありません。使用しているライブラリの Keep ルールに問題がある場合は、ライブラリの作成者に連絡して問題を確認することをおすすめします。
Keep ルールのベスト プラクティス
やってはいけないことがわかったので、ベスト プラクティスについて説明します。
制限が厳しく具体的な Keep ルールを記述する
優れた Keep ルールは、できるだけ制限が厳しく具体的 である必要があります。必要なものだけを保持し、それ以外のすべてを R8 で最適化できるようにする必要があります。
| ルール | 品質 |
|---|---|
| 低: パッケージとそのサブパッケージ全体を保持します |
| 低: クラス全体を保持します。これは広すぎる可能性があります |
-keepclassmembers class com.example.MyClass {
private java.lang.String secretMessage;
public void onNativeEvent(java.lang.String);
} | 高: 特定のクラスの関連するメソッドとプロパティのみが保持されます |
共通の祖先を使用する
複数の異なるデータモデルに対して個別の Keep ルールを記述するのではなく、共通の基本クラスまたはインターフェースをターゲットとする 1 つのルールを記述します。次のルールは、このインターフェースを実装するクラスのメンバーを保持するように R8 に指示し、拡張性が高くなります。
# Keep all fields of any class that implements SerializableModel
-keepclassmembers class * implements com.example.models.SerializableModel {
<fields>;
}アノテーションを使用して複数のクラスをターゲットにする
カスタム アノテーション(@Serialize など)を作成し、フィールドを保持する必要があるクラスに「タグ付け」します。これは、クリーンで宣言型で、拡張性の高いパターンです。使用しているフレームワークの既存のアノテーションに対して Keep ルールを作成することもできます。
# Keep all fields of any class annotated with @Serialize
-keepclassmembers class * {
@com.example.annotations.Serialize <fields>;
}適切な Keep オプションを選択する
Keep オプションは、ルールの最も重要な部分です。間違ったオプションを選択すると、最適化が不要に無効になる可能性があります。
| Keep オプション | 機能 |
-keep | 宣言で言及されているクラスとメンバー が削除または名前変更されないようにします。 |
-keepclassmembers | 指定されたメンバーが削除または名前変更されないようにしますが、クラス自体は削除できます。ただし、削除されないクラスに限ります。 |
-keepclasseswithmembers | 組み合わせ: 指定されたすべてのメンバーが存在する場合にのみ、クラス とそのメンバーを保持します。 |
Keep オプションの詳細については、Keep オプションのドキュメントをご覧ください。
修飾子を使用して最適化を許可する
allowshrinking や allowobfuscation などの修飾子は、広範な -keep ルールを緩和し、最適化の権限を R8 に戻します。たとえば、レガシー ライブラリでクラス全体に -keep を使用する必要がある場合は、圧縮と難読化を許可することで、最適化の一部を取り戻すことができます。
# Keep this class, but allow R8 to remove it if it's unused and allow R8 to rename it. -keep,allowshrinking,allowobfuscation class com.example.LegacyClass
追加の最適化のためのグローバル オプションを追加する
Keep ルールに加えて、R8 構成ファイルにグローバル フラグを追加して、さらに最適化を促進できます。
-repackageclasses は、難読化されたすべてのクラスを 1 つのパッケージに移動するように R8 に指示する強力なオプションです。これにより、冗長なパッケージ名文字列が削除され、DEX ファイルの容量が大幅に節約されます。
-allowaccessmodification を使用すると、R8 はアクセス権を拡大(private から public など)して、より積極的なインライン化を有効にできます。これは、proguard-android-optimize.txt を使用するとデフォルトで有効になります。
警告: ライブラリの作成者は、これらのグローバル最適化フラグをコンシューマー ルールに追加しないでください。アプリ全体に強制的に適用されます。
さらに明確にするため、Android Gradle プラグイン バージョン 9.0 では、ライブラリのグローバル最適化フラグを完全に無視するようになります。
ライブラリのベスト プラクティス
すべての Android アプリは、何らかの方法でライブラリに依存しています。ライブラリのベスト プラクティスについて説明します。
ライブラリ デベロッパー向け
ライブラリでリフレクションまたは JNI を使用する場合は、必要な Keep ルールをコンシューマーに提供する必要があります。これらのルールは consumer-rules.pro ファイルに配置され、ライブラリの AAR ファイルに自動的にバンドルされます。
android {
defaultConfig {
consumerProguardFiles("consumer-rules.pro")
}
...
}ライブラリ コンシューマー向け
問題のある Keep ルールを除外する
問題のある Keep ルールを含むライブラリを使用する必要がある場合は、AGP 9.0 以降の build.gradle.kts ファイルで除外できます。これにより、特定の依存関係からのルールが R8 で無視されます。
release {
optimization.keepRules {
// Ignore all consumer rules from this specific library
it.ignoreFrom("com.somelibrary:somelibrary")
}
}最適な Keep ルールは Keep ルールがないこと
R8 構成の最終的な戦略は、Keep ルールを記述する必要性を完全になくす ことです。多くのアプリでは、リフレクションよりもコード生成 を優先する最新のライブラリを選択することで実現できます。コード生成を使用すると、最適化ツールは、ランタイム時に実際に使用されるコードと削除できるコードをより簡単に判断できます。また、動的なリフレクションを使用しないということは、「隠れた」エントリ ポイントがないため、Keep ルールは不要になります。 新しいライブラリを選択する場合は、常にリフレクションよりもコード生成を使用するソリューションを選択してください。
ライブラリの選択方法について詳しくは、ライブラリを賢く選択するをご覧ください。
R8 構成のデバッグとトラブルシューティング
R8 が保持すべきコードを削除した場合や、APK が想定よりも大きい場合は、次のツールを使用して問題を診断します。
重複する Keep ルールとグローバル Keep ルールを見つける
R8 は数十のソースからルールをマージするため、「最終的な」ルールセットを把握するのは難しい場合があります。このフラグを proguard-rules.pro ファイルに追加すると、完全なレポートが生成されます。
# Outputs the final, merged set of rules to the specified file -printconfiguration build/outputs/logs/configuration.txt
このファイルを検索して、冗長なルールを見つけたり、問題のあるルール(-dontoptimize など)をそのルールを含む特定のライブラリにトレースしたりできます。
R8 に質問する: なぜこれを保持するのですか?
削除されるはずのクラスがアプリに残っている場合、R8 はその理由を教えてくれます。次のルールを追加するだけです。
# Asks R8 to explain why it's keeping a specific class class com.example.MyUnusedClass -whyareyoukeeping
ビルド中に、R8 はそのクラスを保持した原因となった参照チェーンを正確に出力するため、参照をトレースしてルールを調整できます。
完全なガイドについては、R8 のトラブルシューティングをご覧ください。
次のステップ
R8 は、Android アプリのパフォーマンスを向上させる強力なツールです。その効果は、静的解析エンジンとしての動作を正しく理解しているかどうかにかかっています。
具体的なメンバーレベルのルールを記述し、祖先とアノテーションを活用し、適切な Keep オプションを慎重に選択することで、必要なものだけを保持できます。最も高度な方法は、リフレクション ベースの前身ではなく、最新のコード生成ベースのライブラリを選択することで、ルールを完全に不要にすることです。
Performance Spotlight Week に沿って、YouTube で公開されている今日の Spotlight Week の動画を確認し、R8 チャレンジを続けてください。R8 の有効化またはトラブルシューティングに関する質問がある場合は、#optimizationEnabled を使用してください。お知らせください。
特典を実感してください。
今日、アプリで R8 フルモードを有効にすることをおすすめします今日。
- デベロッパー ガイドに従って、アプリの最適化を有効にします。
proguard-android.txtをまだ使用している場合は、proguard-android-optimize.txtに置き換えます。- 次に、影響を測定します 。違いを感じるだけでなく、検証してください。 GitHub の Macrobenchmark サンプルアプリ のコードを適応させて、起動時間を測定し、パフォーマンスの向上を測定します。
アプリのパフォーマンスが大幅に向上すると確信しています。
質問がある場合は、ソーシャル タグ #AskAndroid を使用してください。1 週間を通して、Google のエキスパートが質問をモニタリングして回答します。
明日は、ベースライン プロファイルとスタートアップ プロファイルを使用したプロファイル ガイド付き最適化について説明します。また、過去のリリースで Compose レンダリングのパフォーマンスがどのように向上したか、バックグラウンド作業のパフォーマンスに関する考慮事項についても説明します。
続きを読む
-
プロダクト ニュース
拡張オーバーレイから完全没入型環境まで、Android XR エコシステムは急速に拡大しており、Samsung Galaxy XR はすでに発売されています。
Stevan Silva, Vinny DaSilva • 3 分で読了
-
プロダクト ニュース
Google I/O では毎年、Android 開発を含むエコシステムとプロダクト全体にわたる新しい発表とリソースが提供されます。開発が AI とエージェント支援ツールに移行するにつれて、Android 向けにビルドする方法に関係なく、デベロッパーをより適切にサポートできるよう、提供内容を拡大しました。
Simona Milanovic • 2 分で読了
-
プロダクト ニュース
Google I/O ‘26 では、Android エコシステムの最新の進歩が、開発効率を最大限に高めながらアプリの品質を高めるのにどのように役立つかを紹介しました。
Ataul Munim • 3 分で読了
最新情報の入手
Android 開発に関する最新の分析情報を毎週メールで受け取ります。 毎週。