Lỗi kẹt – treo splash screen khi build file AAB – The AAB Persistent Splash Screen Bug

Lỗi treo splash screen (màn hình khởi động) khi build file AAB (build appbundle). Tên tiếng Anh tạm gọi là AAB persistent splash screen (Tôi cũng không search mạng nên cũng không biết đặt đúng chưa). Đại loại thế nhé.
Khi Flutter hoạt động bình thường trong file APK, nghĩa là build APK chạy bình thường. Nhưng khi build AAB thì bị treo ở màn hình khởi động (splash screen) trong bản dựng trên Play Store.
TMR bình luận: Ai chưa gặp lỗi này thì cũng debug hết hồn. khó chịu. Bài dưới đây là team nhập state và thông tin quá trình debug vào cho AI viết lại giúp. Nhưng cơ bản dùng được. Anh em ai gặp lỗi như này có thể chú ý xử lý theo nhé. Đỡ mất thời gian mày mò.

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:

  1. App mở lên và dừng ở splash screen

  2. Không chuyển sang UI chính

  3. Không crash

  4. Không ANR

  5. adb logcat vẫn trôi đều

  6. flutter run --debugUI hiện ngay

  7. APK build local → OK

  8. 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:

  1. Activity được tạo với LaunchTheme

  2. LaunchTheme áp dụng android:windowBackground

  3. Flutter render UI phía trên content view

  4. 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.xml thiế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)

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
</layer-list>

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

flutter run --debug

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:

android/app/src/main/res/values-v31/styles.xml
android/app/src/main/res/drawable/launch_background.xml

9. Cách fix chuẩn (khuyến nghị)

9.1. Sửa launch_background.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/transparent" />
</layer-list>

9.2. Đảm bảo có values-v31/styles.xml

<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">@android:color/transparent</item>
</style>
<style name=“NormalTheme” parent=“@android:style/Theme.Light.NoTitleBar”>
<item name=“android:windowBackground”>@android:color/transparent</item>
</style>
</resources>
TMR Team bình luận: Đoạn này debug tới lui mà mãi mới phát hiện ra đó. AE chú ý nếu gặp nhé.

9.3. Build lại đúng quy trình

flutter clean
flutter pub get
flutter build appbundle

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.

How useful was this post? 5/5 - (1 bình chọn)