Android アプリをリリースする際にサイズ削減やリバースエンジニアリング対策として ProGuard / R8 による難読化を行います。しかし設定を誤るとクラッシュの原因になったり、重要なクラスやメソッドが削除されてしまうこともあります。ProGuardの役割やクラッシュを防ぐ方法についてメモします。
ProGuard / R8 の役割
ProGuard / R8 は以下の3つを行います。
難読化はリバースエンジニアリング対策になりますが、リフレクションや外部ライブラリを利用するコードが削除されてしまうとクラッシュの原因になります。
- Shrinking: 使われていないクラスやメソッドを削除して APK サイズを削減
- Obfuscation: クラス名やメソッド名をランダムな短い名前に変換して難読化
- Optimization: コードを最適化して実行効率を改善
よくあるクラッシュの原因
ProGuard / R8 でのクラッシュ原因は主に次の2つです。
-
リフレクションを使うコードが削除される*
JSON パーサーや DIフレームワークはリフレクションを多用しています。
必要なクラスを誤って削除すると実行時にClassNotFoundException
やNoSuchMethodException
が発生します -
外部ライブラリでのメソッド名変更
SDK 側がリフレクションで特定の名前を呼び出す場合、難読化で名前が変わるとクラッシュします
よく使う keep 設定例
クラッシュを防ぐためには、必要なクラスやメソッドを keep する設定を行います。代表的な例を紹介します。モデルクラスや DI に関するクラスは削除されないように設定します。
# Gson など JSON パーサーで使用するモデルを保持
-keep class com.example.app.model.** { *; }
# Retrofit
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
# Dagger / Hilt
-keep class dagger.** { *; }
-keep interface dagger.** { *; }
# Kotlin の data class を守る
-keep class kotlin.Metadata { *; }
- ProGuard / R8 は アプリサイズ削減・難読化・最適化を行うツール。
- クラッシュ原因の多くは リフレクション使用部分が削除または改名されること
-
-keep
を適切に設定して重要なクラスやライブラリを保護することで安定動作が可能 - 難読化後は 必ず実機テストを行い、クラッシュが発生しないか確認する