This guide explains how to measure CPU usage on Android devices to identify battery drain issues.
- ADB installed:
brew install android-platform-tools(macOS) - Android device connected with USB debugging enabled
- App built in profile or release mode (avoid debug for CPU measurement)
cd app
flutter build apk --flavor dev --profile --target-platform android-arm64Output: build/app/outputs/flutter-apk/app-dev-profile.apk
adb install build/app/outputs/flutter-apk/app-dev-profile.apk
# Or run directly:
flutter run --profile --flavor dev./scripts/measure_cpu_android.sh -p com.friend.ios.dev -n 15 -d 2 -o /tmp/omi_cpu_baseline.csv./scripts/measure_cpu_android.sh -p <package> [-s <device>] [-n <samples>] [-d <delay>] [-o <csv>]
# Examples:
./scripts/measure_cpu_android.sh -p com.friend.ios.dev -n 15 -d 2
./scripts/measure_cpu_android.sh -p com.friend.ios.dev -n 20 -d 1 -o /tmp/omi_cpu_idle.csv./scripts/compare_cpu_builds.sh \
build/app/outputs/flutter-apk/app-A.apk "version-A" \
build/app/outputs/flutter-apk/app-B.apk "version-B" \
-p com.friend.ios.dev -n 15 -d 2# Single sample
adb shell "top -b -n 1 | grep com.friend.ios.dev"
# Continuous monitoring
adb shell "top -d 2 | grep --line-buffered com.friend.ios.dev"| CPU % | Interpretation |
|---|---|
| 0-10% | Idle - excellent |
| 10-30% | Light activity - good |
| 30-50% | Moderate - acceptable for active use |
| 50-100% | High - potential battery drain |
| >100% | Very high - using multiple cores, investigate! |
Note: CPU >100% means the app is using more than one CPU core. Use median CPU across samples, not single spikes.
- Symptom: High CPU even when idle
- Cause:
Shimmer.fromColorsruns continuous animation - Fix: Replace with static skeleton or use
AnimatedOpacity
- Symptom: CPU spikes on state changes
- Cause: Using
Consumerinstead ofSelector - Fix: Use
Selectorto listen only to specific fields
- Symptom: Constant CPU usage
- Cause: Timers running when not needed
- Fix: Cancel timers when widget disposed or app backgrounded
To compare CPU impact of a change:
# 1. Build baseline APK
git checkout main
flutter build apk --flavor dev --profile
cp build/app/outputs/flutter-apk/app-dev-profile.apk /tmp/baseline.apk
# 2. Build changed APK
git checkout feature-branch
flutter build apk --flavor dev --profile
cp build/app/outputs/flutter-apk/app-dev-profile.apk /tmp/feature.apk
# 3. Compare
./scripts/compare_cpu_builds.sh /tmp/baseline.apk "baseline" /tmp/feature.apk "feature" -p com.friend.ios.dev| Scenario | CPU Usage |
|---|---|
| WITH Shimmer widget | ~135% |
| WITHOUT Shimmer widget | ~41% |
Conclusion: Single Shimmer widget adds ~94% CPU overhead.
- App might be in background or screen off
- Ensure app is in foreground and screen is on
- Wait 10s after app launch before measuring
- Ensure no other heavy apps running
- Keep device plugged in to avoid thermal throttling
- Use
topcommand instead (more accurate for Flutter apps) - The scripts use
topby default
scripts/measure_cpu_android.sh- Single measurement script (median-based)scripts/compare_cpu_builds.sh- A/B comparison script (median-based)integration_test/shimmer_cpu_test.dart- Automated shimmer test