android-data-layer
Use when implementing the data layer in Android or KMP — the Repository pattern's layered error-propagation model (repository as…
Use when debugging Android or KMP issues — Android-specific techniques covering Logcat, ADB, ANR traces, R8 stack trace decoding, memory leaks, Gradle build failures, and Compose recomposition bugs, on a root-cause-first foundation.
$ npx -y skills add rcosteira79/android-skills --skill android-debugging --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/android-debuggingContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when debugging Android or KMP issues — Android-specific techniques covering Logcat, ADB, ANR traces, R8 stack trace decoding, memory leaks, Gradle build failures, and Compose recomposition bugs, on a root-cause-first foundation.
name: android-debugging description: > Use when debugging Android or KMP issues — Android-specific techniques covering Logcat, ADB, ANR traces, R8 stack trace decoding, memory leaks, Gradle build failures, and Compose recomposition bugs, on a root-cause-first foundation.
Android-specific evidence-gathering and investigation techniques on a root-cause-first foundation.
**Root-cause-first foundation:**
The Android-specific tools below serve that investigation. *Optional:* if you run a dedicated debugging-discipline skill (e.g. `superpowers:systematic-debugging` or `ace:systematic-debugging`), this layers on top of it — but it requires none.
# Stream crash logs filtered by app package adb logcat --pid=$(adb shell pidof -s com.example.app) # Save full logcat to file for analysis adb logcat -d > crash_log.txt # Filter by tag adb logcat -s "YourTag:E"
Key logcat log levels: `V` (verbose) `D` (debug) `I` (info) `W` (warn) `E` (error) `F` (fatal)
Read the **full stack trace** — the root cause is usually at the bottom of the `Caused by:` chain, not the top-level exception.
ANRs mean the main thread was blocked. Evidence:
# Pull ANR trace from device adb pull /data/anr/traces.txt ./anr_traces.txt # Or stream while reproducing adb logcat -s "ActivityManager:E" | grep -A 30 "ANR in"
Look for: `main` thread in state `MONITOR` (waiting for a lock) or blocking I/O on `main`. Trace backward to find what holds the lock.
**Common causes:** Database/network call on main thread, `runBlocking` on main thread, deadlock between coroutine scopes.
Add [LeakCanary](https://square.github.io/leakcanary/) to `debugImplementation`. It surfaces leak traces automatically in a notification.
Read the leak trace top-to-bottom: the first bold line is the leaking object, the path shows what's holding the reference. Fix by clearing the reference in the appropriate lifecycle callback.
# Dump heap manually for Android Profiler analysis adb shell am dumpheap com.example.app /data/local/tmp/heap.hprof adb pull /data/local/tmp/heap.hprof ./heap.hprof
For bottleneck investigation across CPU, graphics, I/O, IPC, memory, or power — beyond what Logcat and ANR traces show — capture a Perfetto trace and query it with SQL.
**Measure before you fix.** For performance regressions, logs usually mislead — capture a *baseline* measurement before changing anything, then bisect against it. A trace tells you where time goes; only a comparison against a known-good baseline tells you what actually regressed.
# Capture a trace (system-level, all categories)
adb shell perfetto -c - --txt -o /data/misc/perfetto-traces/trace.pftrace \
<<'EOF'
buffers { size_kb: 65536 }
data_sources { config { name: "linux.ftrace" } }
data_sources { config { name: "android.surfaceflinger.frame" } }
duration_ms: 10000
EOF
adb pull /data/misc/perfetto-traces/trace.pftrace ./Then open the trace at https://ui.perfetto.dev and run SQL against it (`SELECT name, dur FROM slice WHERE dur > 16e6` for frames slower than 16ms, etc.).
For an agent-driven workflow — translating an investigation intent (jank, slow startup, battery drain) into the right Perfetto SQL and iterating across the trace — see Google's [`perfetto-sql`](https://github.com/android/skills/tree/main/profilers/perfetto-sql) and [`perfetto-trace-analysis`](https://github.com/android/skills/tree/main/profilers/perfetto-trace-analysis) skills (`android skills list` to check for a local install; `android skills add perfetto-sql perfetto-trace-analysis` otherwise). They provide Domain Hints (CPU/Graphics/I/O/IPC/Memory/Power), a mandatory scratchpad chain-of-evidence pattern, and `GLOB`-over-`LIKE` query rules.
Release crash stack traces are obfuscated. Decode them with the mapping file generated at build time.
# retrace a crash (AGP 7+) ./gradlew :app:retrace --stacktrace-file crash.txt # Or use the retrace CLI directly java -jar retrace.jar mapping.txt crash.txt
Mapping files are in `app/build/outputs/mapping/<variant>/mapping.txt`. Always archive them alongside release builds.
If a class is unexpectedly removed or renamed, add a `-keep` rule in `proguard-rules.pro` and verify with:
./gradlew :app:assembleRelease # Then inspect: app/build/outputs/mapping/release/usage.txt (removed) and seeds.txt (kept)
For the **inverse problem** — reading obfuscated third-party code or decoding a stack trace from a library where the mapping file isn't yours — `retrace` doesn't apply. Use `jadx --deobf` (consistent renames across the decompiled output) or `jadx --deobf-map` (when the SDK ships a mapping). The [`android-reverse-engineering` plugin](https://github.com/SimoneAvogadro/android-reverse-engineering-skill) covers the full workflow including the anchor-via-strings strategy for navigating obfuscated code by string literals and framework class names that survive obfuscation (check if it's already installed locally first — it ships as `android-reverse-engineering:*` skills).
Read the error from the **bottom up** — Gradle wraps errors in multiple layers.
Common patterns:
| Error | Investigation | |-------|--------------| | `Manifest merger failed` | Check `app/build/intermediates/merged_manifests/` for the merged output; look for conflicting `android:` attributes | | `Duplicate class` | Run `./gradlew dependencies` and look for the same class in multiple
Android & KMP development skills for Claude Code, Codex, and Copilot CLI — architecture, Compose, coroutines, flows, networking, persistence, dependency injection, testing, debugging, and Gradle.
Use when implementing the data layer in Android or KMP — the Repository pattern's layered error-propagation model (repository as…
Use this skill as the baseline for ALL Android and Kotlin Multiplatform (KMP) work — whenever the user mentions Android, Kotlin…
Use when setting up or refactoring Android Gradle build logic — convention plugins, composite builds, version catalogs, and…
Use when setting up or working with Retrofit in Android — service interface definitions, coroutines integration, OkHttp…
Use when needing to fetch Android source code — AOSP platform internals (@hide APIs, framework classes, system services) or…
Use when writing, fixing, or refactoring Android/KMP code in Kotlin — a test-first (RED-GREEN-REFACTOR) foundation plus the…