Lỗi Gặp Phải
Ứng dụng của bạn bị crash ngay khi khởi động — hoặc ngay khi mở một dialog — và logcat hiển thị lỗi sau:
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)
Một dòng giải thích tất cả: theme được gán cho activity của bạn không kế thừa từ Theme.AppCompat. Theme đó được khai báo trong AndroidManifest.xml hoặc styles.xml — và hiện tại nó thuộc sai họ theme. Delegate nội bộ của AppCompatActivity sẽ kiểm tra theme tương thích ngay lúc khởi động. Không có theme tương thích, ứng dụng sẽ không thể khởi chạy.
Nguyên Nhân Gây Lỗi
AppCompatActivity sử dụng delegate nội bộ của AppCompat để backport các thành phần Material và hành vi action bar xuống API 14. Delegate đó tìm kiếm một theme tổ tiên là Theme.AppCompat ngay khi khởi động. Nếu bạn gán cho nó một theme hệ thống thông thường — Theme.Holo, android:Theme.Light, Theme.Material — nó sẽ throw exception ngay lập tức.
Các trường hợp phổ biến nhất gây ra lỗi này:
- Bạn kế thừa
AppCompatActivitynhưng manifest vẫn trỏ đến@android:style/Theme.Lighthoặc tương tự. - Bạn đã chuyển sang AndroidX và cập nhật code Java/Kotlin, nhưng
styles.xmlvẫn còn parent cũ. - Bạn đang tạo
AlertDialogtừ thư viện AndroidX nhưng truyền vàogetApplicationContext()— context này không mang theme của activity. - Một activity của thư viện bên thứ ba có theme override trong manifest của bạn trỏ đến style không phải AppCompat.
Các Bước Sửa Lỗi
Bước 1 — Sửa theme trong styles.xml
Mở res/values/styles.xml. Theme của ứng dụng phải kế thừa từ một biến thể của Theme.AppCompat:
<!-- SAI — theme Android thông thường -->
<style name="AppTheme" parent="android:Theme.Light">
...
</style>
<!-- ĐÚNG — theme AppCompat -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
</style>
Đã dùng Material Design 3? Không sao. Theme.MaterialComponents.* kế thừa từ Theme.AppCompat, nên hoàn toàn hợp lệ:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
...
</style>
Bước 2 — Kiểm tra theme trong AndroidManifest.xml
Kiểm tra cả tag <application> lẫn các override riêng cho từng activity:
<application
android:theme="@style/AppTheme"
... >
<!-- Các override riêng cho activity cũng phải trỏ đến theme AppCompat -->
<activity
android:name=".SettingsActivity"
android:theme="@style/AppTheme.Settings" />
</application>
Lỗi dễ bỏ sót: bạn đã sửa theme cấp ứng dụng, nhưng một activity vẫn còn android:theme="@android:style/Theme.Dialog". Activity đó vẫn sẽ crash.
Bước 3 — Sửa lỗi crash trong dialog
Nếu crash xảy ra bên trong dialog thay vì trong onCreate, nguyên nhân là context bạn đang truyền vào AlertDialog.Builder. Application context và service context không mang theme của activity. Hãy dùng chính activity đó:
// SAI — applicationContext không có theme activity
new AlertDialog.Builder(getApplicationContext())
// SAI — context từ Service hoặc BroadcastReceiver cũng không dùng được
new AlertDialog.Builder(context)
// ĐÚNG — Activity mang theme AppCompat
new AlertDialog.Builder(MainActivity.this)
// ĐÚNG — bên trong Fragment
new AlertDialog.Builder(requireActivity())
Trong Kotlin:
// ĐÚNG
AlertDialog.Builder(requireActivity())
.setTitle("Xác nhận")
.setMessage("Bạn có chắc không?")
.setPositiveButton("Có") { _, _ -> /* hành động */ }
.show()
Bước 4 — Sửa lỗi crash từ activity của thư viện
Nếu stack trace trỏ đến một activity từ SDK bên thứ ba, hãy override theme của nó trong manifest của bạn:
<activity
android:name="com.somelib.SomeActivity"
android:theme="@style/AppTheme" />
Cách này buộc Android áp dụng theme tương thích AppCompat của bạn cho activity thư viện đó, thay vì dùng bất kỳ theme nào SDK đã khai báo.
Kiểm Tra Sau Khi Sửa
- Clean project: chọn Build → Clean Project trong Android Studio, hoặc chạy
./gradlew clean. - Build lại và chạy trên thiết bị hoặc máy ảo.
- Activity khởi động mà không bị crash. Không còn
IllegalStateExceptiontrong logcat. - Layout editor giờ hiển thị theme của bạn thay vì trạng thái lỗi trắng.
- Kiểm tra thủ công từng activity có theme override riêng — mở từng cái để xác nhận.
Các Trường Hợp Đặc Biệt và Lưu Ý
- Style v21 hỗn hợp: Nếu
res/values-v21/styles.xmlvẫn còn parent cũ nhưandroid:Theme.Material, các thiết bị Android 5.0+ sẽ đọc file đó và crash — dù bạn đã sửastyles.xmlgốc. Hãy kiểm tra tất cả các thư mục variant của style. - Layout NoActionBar: Đang xây dựng giao diện toàn màn hình hoặc dùng toolbar tùy chỉnh? Hãy dùng
Theme.AppCompat.Light.NoActionBar(hoặc tương đương của MaterialComponents). Đừng tắt action bar bằng code — hãy khai báo trong theme ngay từ đầu. - Constructor của Custom View: Inflate một custom view có chứa widget AppCompat?
Contexttruyền vào constructor đó phải đến từ một AppCompat activity — không phảigetApplicationContext(). - WindowManager overlay: Các dialog nổi được tạo bằng
TYPE_APPLICATION_OVERLAYkhông thể dùng activity context. Thay vào đó, hãy bọc application context với một theme:new ContextThemeWrapper(appContext, R.style.AppTheme).

