On this page
Crash reporting has two halves: collecting reports from devices, and reading them well enough to find the cause. This reference covers the types of Android failures, where each type of report appears, and a repeatable method for turning a raw stack trace into a fix.
Three kinds of failure
| Failure | What happens | Where you see it |
|---|---|---|
| Java or Kotlin crash | An unhandled exception reaches the framework and the app process stops | logcat, Play Console vitals, Crashlytics |
| ANR | The main thread is blocked, so the system declares the app unresponsive | ANR trace file, logcat, Android vitals |
| Native crash | A fault occurs in C or C++ code, often reported as a signal such as SIGSEGV | Tombstone or native crash dump, logcat |
Where reports come from
Play Console's Android vitals aggregates crashes and ANRs reported from devices running your production release, grouped by exception and by device or Android version. It requires no code on your side and is the first place to look after a rollout.
Firebase Crashlytics adds real-time reporting with custom keys, breadcrumb-style logs, and the ability to record non-fatal errors that do not kill the app but still break a flow. Many teams use Crashlytics during development and testing, then compare what it shows against Android vitals in production.
During your own test pass, logcat is enough. Filtering the crash buffer with adb logcat -b crash shows only failures, which keeps a reproduction run readable while you trigger the bug deliberately.
How to read a stack trace
Start at the top
The top frame is where the exception was thrown. The frames beneath it show the call path that got the app there, which is usually where the actual mistake lives.
Skip framework frames until you hit your package
Frames under android, java, or androidx show how the framework reacted. The first frame with your package name is where your code made the decision that failed.
Read the exception type and message together
The type narrows the cause: a null reference, an index past the end of a list, a permission problem, or a parse failure each point in a different direction. The message often names the exact value that broke.
Reproduce under the reported conditions
Use the device model, Android version, screen state, and preceding steps from the report. A crash that only happens in landscape after a background resume needs those conditions to appear on your desk.
Reading an ANR trace
An ANR trace file contains a thread dump taken while the app was stuck. Find the main thread and read what it was doing: a wait on the wrong thread, a database write on the main thread, or a lock held elsewhere all show up plainly. Unlike a crash, the exception class tells you nothing, because the app was not throwing, it was blocked.
Triage is where most teams lose time, because a pile of raw traces tells you nothing about what to fix first. Grouping crashes by root cause and affected flows turns the list into an ordered backlog, which is part of what AppsTestLab delivers when it runs crash triage alongside an Android App Testing engagement.
Frequently asked questions
Frequently asked questions
Do I need Crashlytics if I have Android vitals?
Vitals covers production after release, at the aggregate level. Crashlytics adds real-time detail, custom keys, and non-fatal errors, which makes it useful earlier in development. Many teams run both.
What if a crash trace points only to framework code?
Look at the message and the call path beneath it. Framework frames often mean an invalid argument was passed in, so the fix is at the first place your code supplied that value.
Sources & references
Official Google documentationThese links open Google's official Play Console Help pages used to verify this guide. AppsTestLab guidance is independent and not affiliated with Google.
Get help doing this
