๐Ÿงช Testing, Debugging, and Performance

Debugging Crashes with Logcat

When an Android app crashes, Logcat holds the answer, usually in the first few lines of a stack trace. This guide teaches you to find the right lines quickly, interpret common exceptions, and turn a crash into a fix and a test.

โœ๏ธ Yunok Tech ๐Ÿ“… Updated โฑ 3 min read ๐ŸŽฏ Beginner
On this page
  1. Find the crash in Logcat
  2. Anatomy of a stack trace
  3. Common exceptions and their usual fixes
  4. From crash to fix: using the debugger
  5. Logging well
  6. Crashes in production
  7. Debugging scenarios
  8. Frequently asked questions
  9. Conclusion

"The app stopped" tells the user nothing and you even less. Logcat, Android's system log, records exactly which exception was thrown, where, and why. Learning to read it is one of the highest-leverage debugging skills you can build.

Find the crash in Logcat

Android Studio's Logcat supports query filters. Useful ones:

Logcat filter examplesText
package:mine level:error          # only your app, errors and above
package:mine tag:OrderRepo        # one tag from your app
FATAL EXCEPTION                   # search for crash headers
is:crash                          # crashes only (newer Logcat versions)

Anatomy of a stack trace

A typical crash (illustrative)Text
FATAL EXCEPTION: main
Process: com.example.shop, PID: 12345
java.lang.IllegalStateException: Product price missing for id=42
    at com.example.shop.cart.CartMapper.toUi(CartMapper.kt:18)
    at com.example.shop.cart.CartViewModel$load$1.invokeSuspend(CartViewModel.kt:34)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(...)
    at kotlinx.coroutines.DispatchedTask.run(...)
    ...
Caused by: kotlinx.serialization.MissingFieldException: Field 'price' is required ...
    at com.example.shop.api.ProductDto$$serializer.deserialize(...)
How to read an Android stack trace Step one: read the exception type and message. Step two: find the first line in your own package, which is where to start looking. Step three: read the Caused by section, which often contains the root cause. Framework and library frames below are usually context. 1. Exception + messagewhat went wrongIllegalStateException:"price missing" 2. First frame in YOUR codewhere to lookCartMapper.kt:18 3. "Caused by"the root causeAPI omitted 'price'
Most crashes are solved by these three reads. Framework frames below your code are usually context, not cause.

Common exceptions and their usual fixes

ExceptionUsual causeTypical fix
NullPointerException!!, platform types from Java, uninitialised lateinitModel nullability; safe calls; initialise properly
IllegalStateExceptionInvalid state: fragment not attached, checkNotNull failed, ViewModel misuseFix lifecycle timing; validate inputs earlier
NetworkOnMainThreadExceptionNetwork call on the main threadCoroutines + suspend APIs
IndexOutOfBoundsExceptionStale index, list changedUse stable keys/IDs; getOrNull
ClassCastExceptionWrong type assumption, often from Bundles or reflectionType-safe navigation arguments; safe casts
Resources$NotFoundExceptionPassing an Int value where a resource ID is expected (setText(42))Convert to String; check resource qualifiers
SecurityExceptionMissing runtime permissionRequest permission; check before use
TransactionTooLargeExceptionLarge Bundle (saved state, intent extras)Pass IDs; persist large data elsewhere

From crash to fix: using the debugger

  1. Click the file link in the stack trace (for example CartMapper.kt:18) to jump to the line.
  2. Set a breakpoint there, or an exception breakpoint for that exception type (Run โ†’ View Breakpoints).
  3. Run in debug and reproduce. Inspect variables and the call stack when it stops.
  4. Write a unit test that reproduces the failing input, fix the code, and watch the test pass.
Regression test for the crash aboveKotlin
@Test
fun `product without price is shown as unavailable instead of crashing`() {
    val ui = CartMapper.toUi(ProductDto(id = "42", name = "Mug", price = null))
    assertEquals("Unavailable", ui.priceText)
}

Logging well

Structured, safe loggingKotlin
private const val TAG = "OrderRepo"

suspend fun placeOrder(order: Order) {
    Log.d(TAG, "placeOrder items=${order.items.size} total=${order.totalPaise}")   // no personal data
    try {
        api.place(order.toDto())
    } catch (e: IOException) {
        Log.w(TAG, "placeOrder failed: network", e)       // include the throwable for its stack trace
        throw e
    }
}
  • Use levels meaningfully: d for debug detail, i for milestones, w for recoverable problems, e for failures.
  • Never log tokens, passwords or personal data.
  • Strip verbose logs from release builds (for example with a logging wrapper or Timber's debug tree).

Crashes in production

Logcat only shows your device. For users' crashes, use Android vitals in the Play Console and a crash reporter such as Firebase Crashlytics. Upload R8 mapping files so stack traces are readable (see R8), and add breadcrumbs and custom keys (screen name, feature flag) to reproduce context.

Debugging scenarios

Crash only in release

Usually R8 or reflection. Reproduce with a minified build and add a targeted keep rule.

Crash after returning from background

Usually process death and a missing lateinit or state. Test with "Don't keep activities".

Crash on one manufacturer

Check Android version, permissions behaviour and WebView or OEM differences in vitals breakdowns.

Frequently asked questions

Logcat is too noisy. What can I do?

Filter by package:mine and level, create saved filters, and use consistent tags.

Why don't I see my logs?

Check the selected device and process, the filter, and that your logging isn't stripped in that build variant.

Can AI help read stack traces?

Yes. Tools like Gemini in Android Studio can explain traces and suggest causes, but verify suggestions against the code. See Debugging with AI.

Conclusion

To debug a crash: filter Logcat, read the exception and message, jump to the first frame in your code, check "Caused by", reproduce with breakpoints, and lock in the fix with a regression test. Use Android vitals and Crashlytics for production crashes.

Next step: automate your quality checks with CI/CD for Android with GitHub Actions.

Official references

๐Ÿ“ฑ Apps built by Yunok Tech

Real Android apps on Google Play, free to download.

See all our apps โ†’

Ready to build real Android applications?

Reading a roadmap is the easy part. The real progress happens when you build a foundation step by step, with someone reviewing your code and answering the questions that come up along the way.

Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.

Explore the Android course and take your next step as an Android developer.

Share: LinkedIn X / Twitter WhatsApp