Top Command-Line Tools to Build, Test, and Debug Android Apps

Command-Line Tools for Android Apps: Essential Utilities for DevelopersCommand-line tools remain indispensable in Android development. They offer speed, repeatability, automation, and fine-grained control that graphical IDEs can’t always match. This article covers the core command-line utilities Android developers should know, how to use them, practical examples, and tips for integrating them into daily workflows and CI/CD pipelines.


Why use command-line tools?

  • Command-line tools are faster for repetitive tasks and scripting.
  • They enable CI/CD automation and reproducible builds.
  • They provide low-level control for debugging, signing, and packaging.
  • They’re lightweight and work well on remote servers and containers.

Core Android command-line tools

Android SDK tools (sdkmanager, avdmanager)

  • sdkmanager installs and updates SDK components (platforms, build-tools, system-images).
    • Example: sdkmanager “platform-tools” “platforms;android-33” “build-tools;33.0.2”
  • avdmanager creates and manages Android Virtual Devices (emulators).
    • Example: avdmanager create avd -n Pixel_API_33 -k “system-images;android-33;google_apis;x86”

adb (Android Debug Bridge)

  • adb is essential for interacting with devices and emulators.
  • Common tasks:
    • List devices: adb devices
    • Install/uninstall apps: adb install app.apk | adb uninstall com.example.app
    • Shell access: adb shell
    • Forward ports: adb forward tcp:8000 tcp:8000
    • Pull/push files: adb pull /sdcard/log.txt ./log.txt | adb push config.json /sdcard/config.json
  • Use adb for automated instrumentation testing and log collection (adb logcat).

fastboot

  • fastboot performs low-level operations on bootloader mode (flashing images, unlocking bootloader).
  • Example: fastboot flash boot boot.img

gradle / ./gradlew

  • Gradle is the primary build system for Android. Use the Gradle Wrapper (./gradlew) for consistent builds.
  • Common tasks:
    • Build APK/AAB: ./gradlew assembleDebug | ./gradlew bundleRelease
    • Run tests: ./gradlew test | ./gradlew connectedAndroidTest
    • Clean: ./gradlew clean
  • Configure build flavors, signing, and proguard/R8 rules in build.gradle files. Use CI to run ./gradlew assemble and ./gradlew test.

aapt / aapt2

  • aapt (Android Asset Packaging Tool) handles packaging, resource processing, and generating R.java. aapt2 is the modern replacement with improved performance.
  • Use for inspecting APK contents and resources:
    • aapt dump badging app.apk
    • aapt2 compile/ link during custom build steps

apksigner / jarsigner

  • apksigner signs APKs with modern APK Signature Scheme v2/v3.
    • Example: apksigner sign –ks mykeystore.jks app.apk
  • jarsigner is older and less preferred for APKs; apksigner is recommended.

bundletool

  • bundletool converts Android App Bundles (.aab) into device-specific APKs (split APKs, universal APKs) and can install them on devices.
    • Generate APK Set: bundletool build-apks –bundle=app.aab –output=app.apks –ks=keystore.jks –ks-pass=file:ks.pass
    • Install on device: bundletool install-apks –apks=app.apks

dexdump / baksmali / smali / dex2jar

  • Tools for inspecting and disassembling DEX bytecode.
    • dex2jar converts DEX to JAR for easier inspection.
    • baksmali/smali disassemble/reassemble DEX files for reverse engineering or patching.

zipalign

  • zipalign optimizes APK file alignment to improve runtime memory usage.
    • Example: zipalign -v -p 4 input.apk output-aligned.apk

monitor, systrace, perfetto

  • Performance and tracing tools:
    • perfetto is the modern tracing system (use via command line or UI).
    • systrace collects system and application trace information (older tool—Perfetto supersedes many use cases).

lint (Android Lint)

  • Run Android Lint from command line: ./gradlew lint
  • Configure checks, baseline files, and fail build on warnings where appropriate.

Developer utilities and supplementary tools

jq, sed, awk, grep

  • Standard Unix text-processing tools for manipulating JSON, logs, and build outputs.
    • Example: adb shell dumpsys activity activities | grep “mResumedActivity”

keytool

  • Java keytool manages keystores, certificates, and keys required for signing.
    • Generate key: keytool -genkeypair -alias mykey -keyalg RSA -keysize 2048 -validity 10000 -keystore mykeystore.jks

curl, httpie

  • For testing APIs from devices or CI, especially when running instrumentation or emulator-hosted services.

openssl

  • Inspect certificates, generate keys, and check TLS configurations for backend services used by the app.

Common workflows and examples

Building and installing debug APK on emulator/device

  1. Build APK: ./gradlew assembleDebug
  2. Locate APK: app-module/build/outputs/apk/debug/app-debug.apk
  3. Install: adb install -r app-debug.apk
  4. Run logs: adb logcat *:S MyAppTag:D

Creating CI pipeline snippet (example with Gradle and apksigner)

  • Steps:
    • Checkout code
    • Install JDK and Android SDK components via sdkmanager
    • ./gradlew assembleRelease
    • zipalign the release APK
    • apksigner sign the APK
    • Run unit and instrumentation tests

Generating device-specific APKs from an AAB

  • Build AAB: ./gradlew bundleRelease
  • Generate APKs: bundletool build-apks –bundle=app-release.aab –output=app.apks –ks=keystore.jks –ks-pass=file:ks.pass
  • Install: bundletool install-apks –apks=app.apks

Automating resource inspection and quick fixes

  • Use aapt2 to compile resources in custom scripts, or run lint in CI and parse results with jq to fail builds on critical issues.

Debugging & reverse engineering via CLI

  • Extract APK: unzip app.apk -d extracted_apk
  • Inspect manifest: aapt dump xmltree app.apk AndroidManifest.xml
  • Convert DEX to JAR: dex2jar classes.dex
  • Disassemble: baksmali disassemble classes.dex -o smali_out
  • Reassemble and sign after modifications using smali -> dex -> rebuild -> apksigner

Best practices

  • Use the Gradle Wrapper (./gradlew) to ensure consistent Gradle versions across environments.
  • Automate repetitive tasks with shell scripts or Makefiles; keep secrets out of repo (use CI secrets).
  • Prefer apksigner and bundletool for modern signing and distribution workflows.
  • Keep SDK components versioned in CI via sdkmanager and accept licenses non-interactively.
  • Run lint and unit tests in CI; run connectedAndroidTest or emulator-based tests selectively due to flakiness and time.
  • Use zipalign and ProGuard/R8 to optimize release builds.

Troubleshooting tips

  • “device not found” with adb: ensure adb server is running (adb start-server), check USB debugging, accept host key on device.
  • Emulator slow: use x86 system images with HAXM/Hypervisor Framework or enable virtualization (KVM on Linux).
  • Signing errors: verify keystore path, alias, and passwords; use apksigner verify to check signatures.
  • Build failures after dependency updates: run ./gradlew –refresh-dependencies and inspect dependency tree with ./gradlew app:dependencies.

Toolchain roadmap (what to learn next)

  • Master Gradle build scripts and custom tasks (Kotlin DSL).
  • Learn bundletool and Play Console artifact management (AAB, signing by Google Play).
  • Deepen knowledge of Perfetto for performance tracing and adb-based profiling.
  • Learn Dockerizing Android build environments and running emulators in CI.
  • Explore advanced bytecode tools (smali/baksmali, ASM) for instrumentation and analysis.

Conclusion

Command-line tools are a force multiplier for Android developers — they enable automation, reproducibility, low-level debugging, and integration with CI/CD. Mastering adb, Gradle, bundletool, apksigner, aapt2, and a few Unix utilities will cover most development and release needs. Incorporate these tools into scripts and CI pipelines to save time, reduce errors, and maintain consistent builds.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *