Sửa lỗi "App" Keeps Stopping trên Android — Hướng dẫn triage nhanh

intermediate📱 Android2026-03-19| Android 8.0–14 (tất cả OEM: Samsung, Xiaomi, Pixel, OnePlus); ảnh hưởng cả app từ Play Store lẫn APK cài thủ công

Error Message

"App" keeps stopping
#android#app-crash#cache#force-stop

Ứng Dụng Cứ Bị Dừng

App của bạn crash ngay khi khởi động — hoặc giữa chừng — và Android hiện một hộp thoại trên màn hình: "App" keeps stopping. Người dùng nhấn OK. App crash lại. Họ nhấn OK lần nữa. Bạn nhận được tin nhắn Slack lúc 2 giờ sáng.

Hộp thoại này xuất hiện khi Android runtime bắt được một exception chưa được xử lý hoặc ANR (Application Not Responding) làm chết tiến trình. Nguyên nhân gốc rễ có thể từ cache bị hỏng, OOM kill, đến cài đặt APK lỗi. Ba vấn đề hoàn toàn khác nhau, một hộp thoại y hệt nhau — vì vậy bước đầu tiên luôn là đọc log.

Debug Nhanh: Đọc Crash Log Trước

Đừng chỉnh bất kỳ cài đặt nào vội. Kết nối thiết bị, bật USB debugging, và kéo logcat về. Câu trả lời thường hiện ra ngay trong 10 dòng đầu tiên.

# Connect device, enable USB debugging, then:
adb logcat -d | grep -E "(FATAL|AndroidRuntime|E/ActivityManager)" | tail -50

# If the app crashes on launch, watch live:
adb logcat *:E | grep -v "^-"

Một crash điển hình trông như sau:

E AndroidRuntime: FATAL EXCEPTION: main
E AndroidRuntime: java.lang.NullPointerException: ...
E AndroidRuntime:   at com.yourapp.MainActivity.onCreate(MainActivity.java:42)

Stack trace đó chỉ thẳng đến dòng code gây lỗi. Một OutOfMemoryError cần cách xử lý rất khác so với NullPointerException — đừng bỏ qua bước này.

Kiểm tra ANR riêng biệt

# ANR traces on older Android versions:
adb pull /data/anr/traces.txt .

# On Android 11+:
adb bugreport bugreport.zip
unzip bugreport.zip && grep -r "ANR" bugreport/

Fix 1: Xóa Cache và Dữ Liệu Ứng Dụng

Cache bị hỏng là thủ phạm phổ biến nhất — đặc biệt sau khi cập nhật OTA hoặc cài đặt bị gián đoạn để lại bytecode cũ.

# Via ADB — this clears BOTH cache and user data:
adb shell pm clear com.example.yourapp

# To clear cache only (non-root), use the UI:
# Settings → Apps → [App Name] → Storage → Clear Cache

Lưu ý: pm clear xóa toàn bộ dữ liệu bao gồm phiên đăng nhập và preferences. Dùng khi bạn muốn bắt đầu hoàn toàn từ đầu. Để giữ nguyên dữ liệu người dùng, hãy dùng đường dẫn qua giao diện ở trên.

Kiểm tra: Khởi động app. Mở bình thường không? Cache là nguyên nhân. Vẫn crash? Log bây giờ sẽ hiển thị lỗi mới mà không bị che khuất bởi trạng thái cũ.

Fix 2: Force Stop, Rồi Khởi Động Lại

Tiến trình có thể đang bị kẹt — crash giữa lúc ghi dữ liệu, đang giữ file lock, hoặc bị kẹt ở trạng thái khởi tạo dở dang. Force-stop sẽ kết thúc tiến trình một cách sạch sẽ.

# Force stop via ADB:
adb shell am force-stop com.example.yourapp

# Relaunch:
adb shell monkey -p com.example.yourapp -c android.intent.category.LAUNCHER 1

Crash biến mất sau khi force-stop? Nghi ngờ có bug về threading hoặc resource leak từ phiên trước. Nó sẽ không tự khắc phục — nhưng bây giờ bạn đã biết chỗ cần đào sâu.

Fix 3: Cài Lại APK

Một lần cài đặt bị lỗi có thể để lại APK hỏng trên thiết bị, khiến app crash mỗi lần khởi động. Nguyên nhân thường gặp: tải xuống bị gián đoạn, bộ nhớ đầy giữa chừng khi cài, filesystem bị hỏng.

# Uninstall cleanly:
adb uninstall com.example.yourapp

# Reinstall:
adb install -r yourapp.apk

# Or from Play Store: uninstall → reinstall from scratch

Với app từ Play Store, hãy kiểm tra xem có bản cập nhật tự động qua đêm nào đó đã đẩy lên phiên bản lỗi không. Tắt tự động cập nhật cho app đó tạm thời, rồi hạ cấp về APK phiên bản trước từ một nguồn đáng tin cậy như APKMirror.

Fix 4: Kiểm Tra Dung Lượng Bộ Nhớ

Bộ nhớ đầy gây ra nhiều vấn đề âm thầm. Android không thể ghi database, giải nén file dex, hoặc tạo file tạm khi /data gần đầy — và crash log thường không nói rõ điều đó.

adb shell df -h /data

# Example output:
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/block/...  64G   63G  0.4G  99%  /data  ← This will cause problems

Đã dùng trên 95%? Xóa cache của nhiều app hoặc chuyển bớt file ra ngoài trước khi thử lại. Trên thiết bị Samsung và Xiaomi, thông báo "bộ nhớ thấp" đôi khi không xuất hiện cho đến khi bạn đã vượt qua ngưỡng gây crash.

Fix 5: OOM Kill (Bản Build Dành Cho Developer)

Không thấy stack trace rõ ràng trong logcat? Tiến trình có thể không hề crash — nó có thể đã bị Android's low memory killer thu hồi.

# Check if OOM killer was involved:
adb logcat -d | grep -i "lowmemory\|lmk\|killed"

# Look for entries like:
I ActivityManager: Killing 12345:com.example.yourapp/u0a123 (adj 900): cached #1

Đây không phải crash. Đây là bị trục xuất khỏi bộ nhớ. Hãy giảm dung lượng bộ nhớ mà app sử dụng, implement các callback onTrimMemory() để giải phóng bitmap và cache chủ động, hoặc thử nghiệm trên thiết bị có ít nhất 4 GB RAM. Tăng dung lượng RAM của emulator là cách giải quyết nhanh trong quá trình phát triển.

Fix 6: Vấn Đề Tương Thích Sau Khi Cập Nhật OS

Crash sau cập nhật thường xảy ra với các app chưa theo kịp các thay đổi API. Hãy kiểm tra target SDK trước:

adb shell dumpsys package com.example.yourapp | grep -E "(targetSdk|versionCode|versionName)"

Một app nhắm tới Android 6 (API 23) nhưng chạy trên Android 14 (API 34) bao gồm 8 phiên bản lớn với nhiều thay đổi hành vi. Giới hạn tiến trình nền, xử lý quyền, và hạn chế intent đều đã bị thắt chặt đáng kể qua các phiên bản đó. Hãy cập nhật app hoặc báo cáo cho nhà phát triển kèm theo phiên bản OS chính xác và model thiết bị.

Danh Sách Kiểm Tra Xác Nhận

  • App khởi động bình thường không có hộp thoại sau khi xóa cache/dữ liệu
  • adb logcat không hiển thị FATAL EXCEPTION cho package đó
  • App hoạt động bình thường khi chuyển từ nền ra foreground (nhấn Home, quay lại)
  • App hoạt động bình thường khi xoay màn hình (nếu áp dụng)
  • Không có mục lmk / OOM nào trong logcat khi sử dụng bình thường

Bài Học Rút Ra

Hộp thoại "App" keeps stopping là cách Android thông báo chung cho mọi trường hợp tiến trình bị chết. Crash, ANR, OOM kill — cả ba đều trông giống hệt nhau với người dùng. Hãy đọc logcat trước khi chỉnh bất kỳ cài đặt nào trên thiết bị. Cách sửa hầu như luôn nằm trong 10 dòng đầu tiên của stack trace.

Trong môi trường production, đừng chờ đến khi có bug report. Hãy cài đặt Thread.setDefaultUncaughtExceptionHandler hoặc tích hợp Firebase Crashlytics hay Sentry. Thiết lập crash reporting chỉ mất khoảng 5 phút. Còn tái hiện một crash âm thầm ở máy local mà không có công cụ đó có thể mất cả ngày.

Related Error Notes