avdbuddy

Project Url: alexstyl/avdbuddy
Introduction: AvdBuddy is a native macOS app for managing Android Virtual Devices without going through Android Studio.
More: Author   ReportBugs   
Tags:

A Kotlin desktop app for managing Android Virtual Devices without opening Android Studio. Built with Compose Desktop, JetBrains Jewel, and Compose Unstyled. No Material UI.

Run

On macOS:

./scripts/runMac

This builds a standalone .app with a bundled JetBrains Runtime and launches it. The first build downloads Gradle, dependencies, and JBR 25 if needed.

For UI development with Compose Hot Reload:

./scripts/runDev
# Equivalent: ./gradlew hotRun --auto

Keep this process running and save Kotlin UI changes. Compose Hot Reload recompiles and updates the running app while retaining its state. It uses the JBR 25 toolchain; normal packaged builds (runMac) do not enable Hot Reload.

Supported application dependencies are managed by KPM in package.yml. Use kpm list to inspect them and kpm i group:artifact:version to add one. Desktop platform selection and test-only dependencies remain in Gradle.

The build requires a JDK to start Gradle. The Gradle toolchain resolver provisions JBR 25, which Jewel requires. Xcode is not required for development.

Features

  • Device sidebar and a large, framed emulator preview
  • Select devices without starting them; stopped previews show the last captured screen in monochrome
  • Central Play button boots/resumes the selected device; new launches run inside the app without a separate emulator window
  • Live color preview with taps, swipes, basic ASCII keyboard input, Back, Home, and Recents
  • Right-click or use the device menu for duplicate, rename, delete, and Show in Finder
  • Guided device creation with Android versions on the left and minor/API releases on the right, plus downloads, device profiles, RAM, internal storage, SD cards, and device frames
  • SDK and emulator storage settings, with SDK validation and unavailable-drive errors
  • Running-device detection and Stop all
  • Diagnostics and Nucleus automatic update checks
  • Keyboard shortcuts: Cmd+N to create, Cmd+, for Settings, and Cmd+Backspace to delete the selected device

Settings imports the SDK and AVD folder preferences from the previous Swift app on first use, including an external or custom device location. Settings are saved in ~/Library/Application Support/AvdBuddy/settings.properties.

SDK discovery checks the saved path, ANDROID_SDK_ROOT, ANDROID_HOME, then ~/Library/Android/sdk. Device storage defaults to ANDROID_AVD_HOME, the Android user/emulator home override, or ~/.android/avd.

Switching emulator folders does not move existing devices or change Android Studio's settings. System images remain under the selected SDK's system-images folder. The app creates regular directories and does not create symlinks. Offline linked storage is reported before an install starts.

For command-line diagnostics, run the packaged app executable with --diagnostics.

The live view currently uses periodic ADB screen captures, rather than a video stream. It is suitable for inspecting and interacting with screens, but animations are not full frame rate and multi-touch is not supported. Devices already launched in an external emulator window can also be previewed; that existing window stays open.

Previews are saved as .avdbuddy-preview.png inside each AVD folder, updated while running and captured again before stopping through AvdBuddy. A previously saved Quick Boot screenshot is used if available. No screenshot is invented for a device that has never been captured. The preview image is separate from Android's Quick Boot state: normal emulator snapshot loading/saving remains enabled.

Verification

./gradlew test

Only backend tests run automatically. They use temporary SDK/AVD fixtures and run headlessly, without opening windows or clicking through the app.

Use Spectre interactively against the running development app for UI inspection. The installed Spectre CLI supplies its agent when attaching; no Spectre dependency is packaged with the app. There are no runnable Compose/Spectre UI tests and no UI test script. Do not add or run automated UI test suites.

./scripts/runDev
# In another terminal, find the AvdBuddy process and attach:
spectre ps
spectre attach <pid>
spectre windows <session-id>
spectre tree <session-id>
# Inspect or interact as needed, then detach:
spectre detach <session-id>

Interactive actions operate on the actual running app and its real devices. The last attach check encountered a Spectre session error; interactive attachment still needs troubleshooting.

Packaging

./gradlew createDistributable
./scripts/releaseMac

The .app is in build/compose/binaries/main/app/. Nucleus packages the DMG, ZIP and latest-mac.yml update metadata beneath build/compose/binaries/main/. These commands only build local artifacts; they do not publish a GitHub release.

Installed direct-download builds check for updates at startup and every 12 hours. About → Check for updates also checks manually. Users download a checksum-verified update and choose Restart and install; restart is disabled during device operations. Automatic checks can be disabled in that window. Development builds skip updates. Homebrew installations use brew upgrade --cask avdbuddy instead.

For a signed, notarized release preparation:

RELEASE_SIGN_IDENTITY='Developer ID Application: …' \
NOTARY_KEYCHAIN_PROFILE='your-notary-profile' \
SPARKLE_TOOLS_DIR='/path/to/Sparkle/bin' \
./scripts/releaseMac -PsignedRelease=true

The Sparkle tools must have access to the existing avdbuddy EdDSA signing key in Keychain. The script creates build/sparkle/appcast.xml and AvdBuddy.dmg for existing Swift installations. It preserves the bundle ID, feed URL and public key; Compose version 1.0.0 uses build 1000, above the previous build 600. The Compose app itself uses Nucleus, not the Swift Sparkle runtime.

Before publishing separately, verify signing/notarization and test an upgrade from an installed Swift release and a Compose release on a test machine. A future v1.0.0 GitHub release must include the Nucleus ZIP and matching latest-mac.yml, plus the signed Sparkle AvdBuddy.dmg and appcast.xml. Keep artifact filenames exactly as referenced by the metadata. Subsequent releases must increment the app version and macOS build number. Homebrew cask sources remain in packaging/homebrew/. Swift sources and Xcode project files have been removed.

Inspired by VirtualBuddy.

MIT · Alex Styl

Apps
About Me
GitHub: Trinea
Facebook: Dev Tools
AI Daily Digest