Skip to main content

ADB-based Android performance metric recorder with live TUI and HTML report

Project description

androidperf

A CLI that records Android app runtime performance over ADB — CPU, RAM, network, FPS/jank, battery, thermal, and screen transitions — draws a live terminal dashboard while it runs, and drops a self-contained HTML report at the end.

┌── androidperf · com.example.app · Pixel 7 (sdk 34)     samples 42  elapsed 00:41 ──┐
│ screen HomeActivity     battery 87% charging 31°C      thermal moderate skin 35°C  │
├──── CPU ────┬── Memory ─────────┬──── Network ────┬──── FPS ────┐
│             │                   │                 │             │
│   19.2 %    │  Total PSS 199 MB │   ↓ rx 5 KB/s   │  fps  58.2  │
│    ▁▂▄▆█    │  Java       39 MB │   ↑ tx 2 KB/s   │  jank 3.1 % │
│             │  Native     44 MB │                 │  p95    18  │
│ per-process │  Graphics   20 MB │       ▁▂        │     █▆▄▂▁   │
│     CPU     │         ▁▂        │       ▁▂        │             │
└─────────────┴───────────────────┴─────────────────┴─────────────┘
                             Ctrl+C to stop

Requirements

Python 3.11 or newer
adb Android Platform Tools on $PATH. macOS: brew install --cask android-platform-tools. Debian/Ubuntu: sudo apt install adb. Windows/other: https://developer.android.com/tools/releases/platform-tools. Verify with adb version.
Android device Physical device or emulator running Android 7.0 (SDK 24) or newerdumpsys gfxinfo framestats needs SDK 24+.
USB debugging Enabled in Developer Options, and the host authorized (adb devices shows the serial as device, not unauthorized).
Python deps Installed automatically: adbutils, typer, rich, jinja2, plotly, pandas.

adb is not a Python package — it's a standalone binary. If androidperf devices says "command not found", that's the missing piece.

Install

pipx install androidperf          # recommended — isolated, globally available
# or
pip install androidperf           # into the current environment

From source (until the package is on PyPI, or if you want to hack on it):

git clone https://github.com/jitinsharma/androidperf.git
cd androidperf

# Option A — globally available, isolated venv managed by pipx:
pipx install .
pipx install --editable .          # if you plan to edit the code

# Option B — a regular venv with the dev extras (pytest, ruff):
python3.11 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

Quickstart

# 1. See connected devices
androidperf devices

# 2. Find the package you want to profile
androidperf packages --filter com.android

# 3. Search app and record
androidperf record

# 3. Launch the app and record for 60s at 1s cadence
androidperf record --package com.android.settings --interval 1 --duration 60

If --package is omitted, record drops into an interactive prompt: type a substring, pick a number.

Attach to an already-running app instead of launching it:

androidperf record --package com.example.app --no-launch

Stop early with Ctrl+C — the JSON and HTML are still written with whatever samples were collected. After the session ends, a stat-card panel prints in the terminal with the same summary numbers that appear in the HTML report.

Each run writes to runs/<timestamp>-<pkg>/:

  • samples.json — raw time-series data, easy to diff or re-plot
  • report.html — single self-contained file, opens offline

What gets measured

Metric Source
CPU % (per-core summed) top -n 1 -b -p <pid>
RAM: PSS / Java / Native / Graphics / Code / Stack dumpsys meminfo <package>
Network rx/tx (per-tick deltas) /proc/net/xt_qtaguid/stats (falls back to dumpsys netstats --uid=<uid> on Android 10+)
Frame rendering rate, jank %, frame p50/p90/p95/p99 dumpsys gfxinfo <package> (window read directly from UptimeStats since for accuracy)
Battery: level, temp, voltage, status dumpsys battery
Thermal: status, skin/cpu/gpu/battery °C dumpsys thermalservice
Activity transitions dumpsys activity activities
Active fragment (top-level + deepest visible child) dumpsys activity <component> — AndroidX FragmentManager apps only

CPU is reported as top's raw %CPU — i.e., summed across cores. 200% means the process is using two cores worth of time. This is the same convention used by Android Studio's CPU profiler.

A note on FPS: Android UI rendering is demand-driven. The app submits a frame only when something on screen changes (animation tick, scroll, view invalidation), so frames/sec goes to zero on a static screen — that's correct, not a bug. androidperf reports it as an activity trace and leads the smoothness summary with jank % and p95 frame time, which are the metrics that actually correlate with perceived smoothness.

HTML report

The report opens with a compact screen-timeline swim-lane (Activity row + Fragment row) showing colored segments across the session — one glance tells you what was on screen when. Below that, the metric charts have a unified hover that includes the active activity + fragment at any timestamp, so you can correlate spikes with user navigation without leaving the chart. The report also includes:

  • Summary stat cards (averages, peaks, network totals, battery delta).
  • Interactive Plotly charts — zoom, pan, hover tooltips, toggle traces in the legend. No network required to view the report; plotly.js is inlined.

Commands

Command Purpose
androidperf devices List connected ADB devices.
androidperf packages [--filter X] [--serial S] [--limit N] List installed packages.
androidperf record --package PKG [...] Record a session; write JSON + HTML.
androidperf report SAMPLES_JSON Regenerate HTML from an existing run.
androidperf version Print installed version.

Development

pytest -q         # parser + report tests (no device required)
ruff check src    # lint

Parsers live under src/androidperf/collectors/ and are tested against captured command output in tests/fixtures/. When you hit a device whose output differs, add a fixture file + an assertion and the parser can be updated against it without any device plugged in.

Layout

src/androidperf/
├── cli.py                # Typer entry point
├── device.py             # adb detection, package list, app launch
├── session.py            # polling loop, signal handling, JSON writer
├── summary.py            # shared summary-card computation (HTML + terminal)
├── collectors/           # cpu, memory, network, fps, battery, thermal, activity, fragments
├── ui/                   # live.py (Live dashboard) + summary.py (end-of-run panel)
└── report/               # Jinja2 + Plotly → self-contained HTML

See plan/ for architecture and future-direction docs.

License

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

androidperf-0.1.2.tar.gz (51.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

androidperf-0.1.2-py3-none-any.whl (35.2 kB view details)

Uploaded Python 3

File details

Details for the file androidperf-0.1.2.tar.gz.

File metadata

  • Download URL: androidperf-0.1.2.tar.gz
  • Upload date:
  • Size: 51.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for androidperf-0.1.2.tar.gz
Algorithm Hash digest
SHA256 253643fdbf37364187ee7d82a4c0f0803c1bb58a5b4abcd0f08f99cce69c24ba
MD5 3ac119ca2129051b14601aa87b597071
BLAKE2b-256 48dfc29b81ba6bc65f609457347e206a32ed75c8ce95dee9594b03b30ba068a5

See more details on using hashes here.

File details

Details for the file androidperf-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: androidperf-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 35.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for androidperf-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7ba7c82f8d32d8691d993c18da7a70bdc9e198aec55f485b6533cc59e639c21a
MD5 6174908af8e9a4725fc099552fca8ecd
BLAKE2b-256 2817f3155235d6d0dc88b4308a6a638d8d0a05a4b22691b36f0b332a20ed0187

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page