エラーの内容
アプリが起動時、またはダイアログを開いた瞬間にクラッシュし、logcatに以下のログが表示されます:
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:852)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:659)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:540)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:170)
at com.example.app.MainActivity.onCreate(MainActivity.java:22)
原因は一行で説明できます:アクティビティに割り当てられているテーマが Theme.AppCompat を継承していないためです。このテーマは AndroidManifest.xml または styles.xml で設定されており、現在は互換性のないテーマファミリーが使われています。AppCompatActivity の内部デリゲートは起動時に互換性のあるテーマを確認します。互換テーマが見つからなければ、アプリは起動できません。
発生原因
AppCompatActivity は AppCompat の内部デリゲートを使って、Material コンポーネントやアクションバーの動作を API 14 まで後方互換させています。このデリゲートは起動時に Theme.AppCompat の祖先テーマを探します。Theme.Holo、android:Theme.Light、Theme.Material といったプレーンなシステムテーマを割り当てると、即座に例外がスローされます。
よくある発生パターンは以下の通りです:
AppCompatActivityを継承しているのに、マニフェストで@android:style/Theme.Lightなどのテーマを指定している。- AndroidX に移行して Java/Kotlin コードは更新したが、
styles.xmlの親テーマが古いままになっている。 - AndroidX ライブラリの
AlertDialogを生成する際にgetApplicationContext()を渡している(アプリケーションコンテキストにはアクティビティのテーマが含まれていない)。 - サードパーティライブラリのアクティビティに対して、マニフェストで AppCompat 非対応のスタイルをテーマとして上書き指定している。
手順別の修正方法
手順 1 — styles.xml のテーマを修正する
res/values/styles.xml を開きます。アプリのテーマは Theme.AppCompat のバリアントを継承している必要があります:
<!-- 誤り — プレーンな Android テーマ -->
<style name="AppTheme" parent="android:Theme.Light">
...
</style>
<!-- 正しい — AppCompat テーマ -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
</style>
すでに Material Design 3 を使用している場合も問題ありません。Theme.MaterialComponents.* は Theme.AppCompat を継承しているため、条件を満たしています:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
...
</style>
手順 2 — AndroidManifest.xml のテーマを確認する
<application> タグとアクティビティごとのテーマ上書きの両方を確認します:
<application
android:theme="@style/AppTheme"
... >
<!-- アクティビティごとの上書きも AppCompat テーマを指定する必要があります -->
<activity
android:name=".SettingsActivity"
android:theme="@style/AppTheme.Settings" />
</application>
見落としがちな点:アプリレベルのテーマは修正したのに、特定のアクティビティにまだ android:theme="@android:style/Theme.Dialog" が残っているケースです。そのアクティビティは引き続きクラッシュします。
手順 3 — ダイアログのクラッシュを修正する
クラッシュが onCreate ではなくダイアログの中で発生する場合、原因は AlertDialog.Builder に渡しているコンテキストです。アプリケーションコンテキストやサービスコンテキストにはアクティビティのテーマが含まれていません。アクティビティ自身を使用してください:
// 誤り — applicationContext にはアクティビティのテーマがない
new AlertDialog.Builder(getApplicationContext())
// 誤り — Service や BroadcastReceiver のコンテキストも使用不可
new AlertDialog.Builder(context)
// 正しい — Activity が AppCompat テーマを持っている
new AlertDialog.Builder(MainActivity.this)
// 正しい — Fragment の中で使用する場合
new AlertDialog.Builder(requireActivity())
Kotlin の場合:
// 正しい
AlertDialog.Builder(requireActivity())
.setTitle("確認")
.setMessage("よろしいですか?")
.setPositiveButton("はい") { _, _ -> /* 処理 */ }
.show()
手順 4 — ライブラリアクティビティのクラッシュを修正する
スタックトレースがサードパーティ SDK のアクティビティを指している場合は、マニフェストでそのテーマを上書きします:
<activity
android:name="com.somelib.SomeActivity"
android:theme="@style/AppTheme" />
これにより、SDK が宣言したテーマの代わりに、AppCompat 互換のテーマを Android がそのライブラリアクティビティに適用するようになります。
修正の確認
- プロジェクトをクリーンにします:Android Studio で Build → Clean Project を実行するか、
./gradlew cleanを実行します。 - 再ビルドして、デバイスまたはエミュレーターで実行します。
- アクティビティがクラッシュせずに起動します。logcat に
IllegalStateExceptionが出力されません。 - レイアウトエディターで、空白のエラー状態ではなくテーマが正しくレンダリングされます。
- アクティビティごとのテーマ上書きがあるすべてのアクティビティを一つずつ開いて確認します。
エッジケースとヒント
- v21 スタイルの混在:
res/values-v21/styles.xmlにandroid:Theme.Materialなどの古い親テーマが残っている場合、ベースのstyles.xmlを修正した後でも、Android 5.0 以上のデバイスはそのファイルを読み込んでクラッシュします。すべてのスタイルバリアントフォルダーを確認してください。 - NoActionBar レイアウト: フルスクリーンやツールバーベースの UI を作成する場合は、
Theme.AppCompat.Light.NoActionBar(または MaterialComponents の同等テーマ)を使用してください。コードでアクションバーを無効にするのではなく、最初からテーマで設定しましょう。 - カスタムビューのコンストラクタ: AppCompat ウィジェットを含むカスタムビューをインフレートする場合、コンストラクタに渡す
Contextは AppCompat アクティビティから取得する必要があります。getApplicationContext()は使用できません。 - WindowManager オーバーレイ:
TYPE_APPLICATION_OVERLAYで作成するフローティングダイアログはアクティビティコンテキストを使用できません。代わりにアプリケーションコンテキストをテーマでラップしてください:new ContextThemeWrapper(appContext, R.style.AppTheme)。

