Android apps crash silently. A user kills the app, clears it from recents, and moves on — but you never hear about it. Unlike web apps where 500s land in your server logs, Android exceptions happen in the user's pocket, and without error tracking, they're gone forever. Android error tracking captures those crashes along with the breadcrumbs, device context, and release info you need to fix the bug before your next review cycle.
This guide sets up production-grade crash reporting in a Kotlin or Java Android app using the Sentry SDK, pointed at LightTrace. By the end you'll capture uncaught exceptions, native crashes, and thread failures with readable stack traces, symbolicated source maps, and crash-free metrics per release.
Install and initialize the SDK
Start by adding the Sentry SDK to your app's build.gradle. LightTrace speaks the Sentry protocol, so you use the standard sentry-android package and change only the DSN.
dependencies {
implementation 'io.sentry:sentry-android:7.15.0'
}
Initialize the SDK once at startup, ideally in your Application class or your main Activity:
import android.app.Application
import io.sentry.Sentry
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
Sentry.init { options ->
options.dsn = "https://<key>@your-lighttrace-host/1"
options.environment = BuildConfig.BUILD_TYPE
options.release = "com.example.app@${BuildConfig.VERSION_NAME}"
options.tracesSampleRate = 1.0
}
}
}
From that moment on, any uncaught exception — a null reference, a network timeout, a main thread ANR — is captured automatically. You don't need try/catch blocks everywhere; the SDK hooks into Android's default exception handler and reports silently in the background.
An event is a single crash. An issue groups all events with the same root cause using fingerprinting. LightTrace shows you issues because that's what you fix — you fix causes, not individual occurrences.
Capture Java and Kotlin exceptions
The SDK catches unhandled exceptions automatically, but you can also report caught exceptions manually — useful for background jobs or network failures that don't crash the app but still matter:
try {
val data = fetchUserData(userId)
} catch (e: Exception) {
Sentry.captureException(e)
// Handle the error locally
}
For Kotlin coroutines, wrap your suspend functions so cancellation doesn't trigger false crashes:
launch {
try {
val result = apiService.getUserData()
} catch (e: Exception) {
if (e is CancellationException) throw e
Sentry.captureException(e)
}
}
Symbolicate native crashes
Android apps can crash in C/C++ code — in the OpenGL renderer, in a native library, or in the garbage collector. Those crashes are harder to read because the stack trace contains memory addresses instead of function names. Symbolication maps those addresses back to your real source.
Upload your app's native symbols (.so debug information) as part of your CI/CD pipeline, and LightTrace will automatically map crashes to readable frames. If you're using Android Studio's Gradle plugin, symbols are generated during the build:
# Extract and upload native symbols to LightTrace
adb logcat | grep sentry # Monitor Sentry events
For a detailed walkthrough on uploading symbols, see our guide on how to add error tracking to any app.
Add context so crashes are fast to fix
A stack trace is a starting point. The real speed-up comes from context — which user crashed, what release broke them, and what they did just before it failed. Set the user ID and add breadcrumbs at meaningful moments:
// Set the user so you know who hit the crash
Sentry.setUser(
User().apply {
id = userId
email = userEmail
}
)
// Breadcrumbs record events leading up to the crash
Sentry.addBreadcrumb(
Breadcrumb().apply {
category = "user-action"
message = "Opened photo library"
level = SentryLevel.INFO
}
)
// Tag events with custom data
Sentry.setTag("device-storage", deviceStorageMB.toString())
Sentry.setContext("purchase", mapOf("planId" to planId, "price" to price))
Now every crash arrives with the breadcrumb trail that led to it, so you can reproduce the exact sequence instead of guessing.
Monitor ANRs and OutOfMemoryError
The two deadliest Android crashes are ANR (Application Not Responding) and OutOfMemoryError. An ANR happens when the main thread stalls for more than 5 seconds; OutOfMemoryError means the app ran out of heap. Both are silent failures that kill the app without a stack trace — unless you're tracking them.
Enable ANR detection in your Sentry config:
Sentry.init { options ->
options.anrEnabled = true
options.anrTimeoutIntervalMillis = 5000 // Sentry default
}
OutOfMemoryErrors are rare but catastrophic. They usually signal a memory leak or a dataset too large for the heap. LightTrace captures the leading breadcrumbs before the crash, giving you context — was the app in a specific screen? uploading a large file? See how to fix Android ANRs and OutOfMemoryError for deep dives on diagnosis.
Profile memory usage in Android Studio and watch for retained objects before they become production crashes. A memory leak that crashes 1% of sessions will kill your crash-free rate and tank your app store rating.
Tag releases so you know which deploy broke things
If a crash started spiking yesterday, the first question is: which release introduced it? Tag every event with a release so LightTrace can show you which deploy is the culprit:
Sentry.init { options ->
options.release = "com.example.app@${BuildConfig.VERSION_NAME}+${BuildConfig.VERSION_CODE}"
options.environment = if (BuildConfig.DEBUG) "dev" else "production"
}
When you deploy a new build, increment VERSION_NAME or VERSION_CODE. Now every crash is labeled with the exact release, and you can track release health to spot regressions in seconds. A new issue in the latest release gets your attention immediately; a spike in an old release tells you users are running old versions.
Monitor crash-free rate
Your app's crash-free rate is the percentage of sessions that don't crash. It's the single clearest signal of stability and the metric that predicts retention — a 1% drop in crash-free rate costs you users and reviews.
LightTrace calculates crash-free sessions and users automatically from your events. Once you tag releases, you can see exactly which deploy caused a regression:
- Crash-free sessions:
(sessions without a crash) / (all sessions) - Crash-free users:
(users who never hit a crash) / (all users)
If a release drops crash-free rate from 99.2% to 98.1%, that's statistically significant and needs a rollback. Read more in crash-free rate: the metric that predicts retention.
Test crash reporting locally
Before deploying, verify your crashes are being captured and formatted correctly. Send a test crash:
// In a dev screen or through a menu option
if (BuildConfig.DEBUG) {
throw Exception("Test crash to verify Sentry is working")
}
Check your LightTrace dashboard — the crash should appear within a few seconds, with the full stack trace, breadcrumbs, device info, and any tags you set.
Sentry has a built-in test mode. Call Sentry.captureMessage("Test message") to verify your DSN is correct and events are flowing before you deploy to production.
From crash to fix in minutes
With error tracking in place, your team's workflow changes. A new issue lands in LightTrace with a stack trace pointing to the exact line, breadcrumbs showing the path that led there, and a user count telling you how many people hit it. You don't wait for reviews or customer complaints — you see it, you fix it, you deploy the next version. The gap from production bug to fix collapses from days to minutes.
LightTrace works alongside the standard Sentry SDK, so if you're already using Sentry, switching is a DSN swap. And because crash-free rate matters for app store rankings, tracking it is no longer optional — it's table stakes.
Start tracking errors in minutes
Point your Android app's Sentry SDK at LightTrace and watch your first crashes land in your dashboard in minutes — free up to 5,000 events a month.
Android crash reporting isn't a luxury. Every untracked crash is a user you lost and a bug that might hit again tomorrow. Start capturing today, and turn silent failures into issues you actually know about.