1. Định nghĩa lỗi
AAB Persistent Splash Screen là một lỗi đặc thù trên Android, xảy ra khi:
Ứng dụng Flutter chạy bình thường ở debug / APK,
nhưng khi build Android App Bundle (AAB) và phân phối qua Google Play,
app kẹt vĩnh viễn ở splash screen, không crash, không ANR, logcat vẫn chạy.
Điểm nguy hiểm của lỗi này là:
-
Không có error rõ ràng
-
Không tái hiện được bằng
flutter run -
Rất dễ bị chẩn đoán nhầm sang Flutter logic, async, Firebase, hoặc lifecycle
2. Bối cảnh thực tế nơi lỗi thường xuất hiện
Lỗi này thường xuất hiện trong các dự án có đặc điểm sau:
-
App Flutter dùng custom splash screen
-
Build AAB để upload Play Console
-
Target Android 12+ (API 31 trở lên)
-
Debug APK không có vấn đề, chạy bình thường
-
Release APK (local) cũng không có vấn đề
-
Chỉ AAB qua Play Store bị kẹt splash. Và rất nguy hiểm nếu anh em dev không chạy test lại file AAB thì không thể phát hiện ra lỗi này.
Điều này khiến nhiều team debug sai hướng, vì:
-
Flutter code chạy đúng
-
Service không block
-
Không có exception
-
Không có ANR
-
Không có crash report trên Play Console
3. Triệu chứng đặc trưng (Key Symptoms)
Nếu bạn gặp tất cả các dấu hiệu sau, khả năng cao bạn đang gặp đúng lỗi này:
-
App mở lên và dừng ở splash screen
-
Không chuyển sang UI chính
-
Không crash
-
Không ANR
-
adb logcatvẫn trôi đều -
flutter run --debug→ UI hiện ngay -
APK build local → OK
-
AAB upload Play → kẹt splash
Đây là pattern rất điển hình của lỗi AAB persistent splash screen.
4. Tên lỗi đề xuất (để dev dễ tìm ra khi fix bug)
Để dễ chia sẻ và tra cứu, có thể gọi lỗi này là:
AAB Persistent Splash Screen due to Opaque LaunchTheme Background
Hoặc ngắn gọn hơn trong nội bộ team:
AAB Splash Overlay Bug
5. Nguyên nhân gốc (Root Cause)
❗ Lỗi KHÔNG nằm ở Flutter
Điểm quan trọng cần khẳng định trước:
-
Flutter đã render frame đầu tiên
-
UI Flutter đã chạy
-
Không có deadlock Dart
-
Không có lỗi async init
❗ Lỗi nằm ở Android native layer – cụ thể là window background
Cơ chế Android (điểm mấu chốt)
Khi app Android khởi động:
-
Activity được tạo với
LaunchTheme -
LaunchThemeáp dụngandroid:windowBackground -
Flutter render UI phía trên content view
-
Nhưng window background không tự động biến mất
Nếu windowBackground là:
-
màu trắng
-
màu đen
-
hoặc drawable opaque
→ UI Flutter bị che phía sau, dù Flutter đã render thành công.
6. Vì sao lỗi chỉ xảy ra với AAB, không xảy ra với APK?
Đây là phần khiến lỗi này rất khó đoán.
Sự khác biệt giữa APK và AAB
-
APK local:
-
dùng resource base
-
không bị Play Store tái đóng gói
-
nhiều khi không kích hoạt resource split theo SDK
-
-
AAB qua Play Store:
-
Play Store repackage app
-
Tách resource theo:
-
ABI
-
Density
-
API level (values-v31, v33, …)
-
-
Android 12+ ưu tiên values-v31
-
👉 Nếu:
-
values/styles.xmlđã sửa -
nhưng
values-v31/styles.xmlthiếu hoặc vẫn dùng background cũ
→ AAB trên Android 12+ vẫn dùng splash opaque, gây lỗi.
7. Ví dụ lỗi điển hình
launch_background.xml (SAI)
Dòng này tưởng như vô hại, nhưng chính là nguồn gốc lỗi.
8. Cách debug đúng (để không đi lạc hướng)
Bước 1: Xác nhận Flutter không lỗi
Nếu UI hiện ngay → Flutter OK.
Bước 2: Nhớ rằng debug không tái hiện lỗi AAB
Debug chỉ dùng để:
-
xác nhận Flutter render
-
loại trừ logic bug
Không dùng debug để kết luận “production OK”.
Bước 3: Kiểm tra resource Android 12+
Bắt buộc kiểm tra:
9. Cách fix chuẩn (khuyến nghị)
9.1. Sửa launch_background.xml
9.2. Đảm bảo có values-v31/styles.xml
9.3. Build lại đúng quy trình
Không clean = rủi ro Play dùng resource cũ.
10. Vì sao lỗi này khó debug và phát hiện
-
Không có stacktrace
-
Không có crash
-
Không có log rõ ràng
-
Rất dễ bị hiểu nhầm là:
-
Firebase init lỗi
-
async deadlock
-
isolate bị block
-
Provider sai
-
Nhiều team mất vài ngày debug Flutter, trong khi lỗi chỉ nằm ở 1 dòng XML native.
11. Checklist phòng tránh lỗi AAB persistent splash screen
Bạn có thể dùng checklist này cho mọi app Flutter Android:
-
Không dùng background opaque cho LaunchTheme
-
Kiểm tra
values-v31/styles.xml -
Test AAB qua Play Internal Test
-
Không tin APK local để kết luận production
-
Nếu “APK OK – AAB kẹt splash” → kiểm tra splash native trước tiên
12. Kết luận
AAB Persistent Splash Screen không phải là lỗi Flutter, mà là lỗi tích hợp Flutter–Android–Play Store.
Hiểu đúng cơ chế:
-
window background
-
resource split theo API
-
sự khác biệt APK vs AAB
sẽ giúp bạn:
-
debug nhanh hơn
-
tránh sửa sai chỗ
-
và ship production an toàn hơn.

