← Back to Blog

Where Android Emulator fits in a robust Capacitor development loop

Published August 24, 2026Updated September 1, 202611 min read
AndroidAndroid EmulatorCapacitorDeveloper Tooling

In Capacitor development, web code runs inside a native mobile shell. I use a web preview, a virtual device, and a physical phone to get the right kind of feedback for each change.

Layer Use it for Main blind spot
Web app Fast UI and shared-code feedback Native shell, WebView, plugins, and mobile lifecycle
Android Emulator or iOS Simulator Routine mobile integration, packaging, lifecycle, and repeatable development checks Real hardware, performance, OEM software, and some store behavior
Physical phone Real-device checks for hardware, performance, connectivity, default apps, and release context Slower to reset, harder to automate, and limited to the devices you own

For me, virtual devices are often the sweet spot: they exercise the mobile shell and integrations while remaining faster to reset and automate than physical phones.

How the middle layer earned its place

At one company, we first introduced Android emulators and Apple simulators. Then we found problems they did not expose, so the company provided physical phones. Those phones helped us find more bugs and corner cases. We kept both virtual and physical devices. For routine build-and-run work, starting a virtual device that was already configured was quicker than connecting and preparing one of those phones. It was also easier to reset or discard.

Physical phones also have a setup cost. Taking several of them away from the desk means carrying cables, chargers, and sometimes adapters. For projects where phones need to reach a development environment running on my laptop over Wi-Fi, I also have to create a temporary network and configure each phone. A virtual device is already on the laptop and can use the host connection. Away from the desk, it is simply easier to start.

My opinion about Android Virtual Devices also changed over time. I used Genymotion personally and initially treated AVD as the less convenient option. Companies I worked with usually did not see enough additional value in adopting another emulator. After learning how much of AVD could be controlled from the command line, I found that a properly configured AVD gave me more control over setup, recovery, and integration than I had expected. AVD became my preferred option.

Side note: Apple’s Simulator and Android Emulator are implemented differently. Apple describes Simulator as running simulator builds directly on the Mac. Android uses a virtual-machine model that can run through a hypervisor. In everyday development, both provide a fast, controllable environment for running a mobile build before checking real hardware.

AVDs are commonly started from Android Studio’s Device Manager. I prefer running Android Emulator as a standalone tool. The Android and iOS workflows then feel coherent: start a virtual device, build the app, install it, and inspect the result without making either IDE the center of the process.

Choose the Android image by capability

An Android Virtual Device (AVD) boots from a system image: the packaged Android operating system for that virtual device. The available images differ in the capabilities and restrictions they include.

Google APIs images include access to Google Play services. Play Store images also include the Play Store and are release-signed, which means they do not allow the elevated root access used by some development workflows.

That distinction mattered in one Capacitor setup. The app needed to reach a development service on the host while preserving its expected HTTPS hostname and WebView origin. Inside the AVD, 10.0.2.2 is a special alias for the development host’s loopback interface. The setup mapped a development hostname to that address. Doing so required a writable system partition, root access, and remounting that partition.

The Google APIs image let me run adb root and adb remount, then change the hosts file. The Play Store image did not. I therefore choose between them based on the system access the workflow needs.

For a long time, I avoided Play Store images because I believed they were slower. On my machine, the Play Store image’s median cold boot took 20 seconds, compared with 22 seconds for Google APIs. The sample was small and host-dependent, so I do not treat it as a general speed ranking.

A Google APIs image is my daily default: it provides access to Play services with enough system control for this scripted setup. For broader release confidence, I switch to a physical phone, which adds real hardware, performance, OEM software, and default apps. I keep Play Store images for testing release-signed restrictions and creating a clean, disposable store environment.

Four tools cover the AVD lifecycle

The CLI became much easier once I gave each tool one job:

  • sdkmanager installs SDK packages.
  • avdmanager creates and deletes device definitions.
  • emulator lists and boots those devices.
  • adb drives a running device: install, launch, inspect logs, move files, and change settings or emulated conditions.

It is a useful exercise to run these commands manually and explore their capabilities before wrapping them in scripts.

A developer can type these commands directly. The same commands also work in scripts and agent workflows.

A team script can choose an AVD, build, install, launch, collect logs, and surface the failures the team has chosen to treat as blocking. I recently wrapped our setup, build-and-run, and live-reload flows into agent skills. The team now uses these skills and AVD scripts daily to speed up development and testing.

Because provisioning and daily operation use separate tools, a stale setup can stay hidden for a long time. My existing AVD kept running through emulator and adb, while creating a new one failed because sdkmanager and avdmanager had not been updated with the rest of the toolchain. Reinstalling current Command-line Tools did not fix the problem until I updated PATH, which still pointed to obsolete binaries.

Before provisioning, check which binaries will run:

command -v sdkmanager avdmanager emulator adb
sdkmanager --version
emulator -accel-check
emulator -list-avds
adb devices

Android documentation recommends ANDROID_HOME and marks ANDROID_SDK_ROOT as deprecated. Older manuals, and AI answers based on them, may still use the old name.

For a quick manual run, the daily loop is short. Choose an unused even-numbered emulator console port; Android Emulator pairs it with the next port for ADB. Using that same console port in SERIAL keeps every command pointed at the same emulator:

PORT=5554
SERIAL="emulator-$PORT"

emulator -avd Medium_Phone_API_36 -port "$PORT" &
adb -s "$SERIAL" wait-for-device
adb -s "$SERIAL" shell 'until [ "$(getprop sys.boot_completed)" = "1" ]; do sleep 1; done'
adb -s "$SERIAL" install -r ./app-release.apk

Boot, connect, wait for Android, then install. adb wait-for-device only waits for the ADB connection, so the next line waits for Android itself. Team automation should also add a boot timeout and cleanup.

Recover only as much state as necessary

An AVD is useful partly because its state has several recovery levels. Android’s snapshot model usually lets me try a smaller reset before deleting the device. When an AVD acts strangely, I move through these reset options:

Level Use it when State boundary
Quick Boot You want the fastest startup and trust the saved state Restores the saved AVD state, including apps and settings
Cold boot with -no-snapshot-load My usual choice when I want to avoid snapshot surprises Starts the OS without loading a snapshot but keeps writable user data
Start with -wipe-data You need clean app data, settings, or a first-install check Recreates user data and removes installed apps and settings, but not an emulated SD card
Delete and recreate the AVD The definition itself is suspect or nothing from it should remain Removes the AVD definition, after which provisioning must create it again

Installed apps and files in the AVD’s user data persist through Quick Boot and cold boot. Wipe data and recreating the AVD remove them.

The recorded startup times were 7 seconds for a confirmed Quick Boot, 22 seconds for a cold boot, and 44 seconds for the initial boot. These are the times from my machine during a regular workload. For me, 22 seconds is cheap enough that I generally prefer a cold boot, while the longer initial boot keeps recreation as the final recovery step.

If an image feels slow, start with emulator -accel-check. Host and guest architecture, RAM pressure, disk space, graphics mode, and snapshot state can all affect performance.

Know when virtual is not enough

Virtual devices provide a controlled, repeatable environment. They do not include every part of a user’s phone.

On one Samsung phone, an important web flow opened in the user’s default Samsung Internet browser rather than the Chrome path we had tested. Samsung Internet is Chromium-based, but it has its own cookie, privacy, and tracking controls. Those settings can change how the same site behaves. Our generic AVD with a controlled browser did not include that default-app environment.

Physical phones also add real performance, memory pressure, connectivity, optional hardware, manufacturer services, and preinstalled apps. After more than ten years in mobile development, I still prefer adding one constrained physical phone when the goal is to expose more real-world failures.

Among Android developers I knew, the LG K9 became a memorable example. We joked that this low-end phone was a legendary bug finder because it exposed problems that more capable phones missed.

My rule is to choose the weakest phone the product actually supports. Testing an obsolete phone outside that range tells me little about the failures current users will see.

Production monitoring can refine the choice. If an issue clusters on one exact model, OS, firmware, or WebView combination, that is a stronger reason to acquire or reserve the device than a general belief that obscure manufacturers cause more bugs. Platform-only stack frames and one-off Application Not Responding (ANR) events give me only a place to start investigating.

Use device matrices selectively

It is worth remembering that you can launch more than one emulator at once. I can use multiple local AVDs or a hosted device matrix to run the same check across several configurations. Options include:

I have mostly seen teams use these services for selected checks, if at all. Local and manual checks remain the daily default.

Agents reuse the same device controls

The CLI scriptability described earlier also supports agents. The device work does not change: start a virtual device, wait for Android, install the app, and collect a screenshot, log, or test result. An agent needs a way to call those steps and inspect what they return.

Some current tools wrap this lower-level device control in an interface built for agents. Apple’s Device Hub puts simulated and physical devices in one place. Apple’s coding-agent workflow can operate the simulated device and return screenshots and test summaries, while devicectl provides a command-line route for scripts and CI.

Claude Code Desktop can place an interactive iOS Simulator pane beside the conversation. Other agent workflows can connect through lower-level tools: OpenAI documents an iOS Simulator workflow through XcodeBuildMCP.

These examples use iOS, but the relationship is the same as in the Android workflow described above: device commands perform the work, while the agent integration decides when to run them and returns the result.

Android’s experimental AppFunctions API lets developers expose selected app actions as tools that authorized callers can discover and execute. This sits at a different layer: the caller invokes an action declared by the app instead of driving each step through the device UI. It covers only the actions the app declares, and full system-agent access remains limited during the experimental rollout.

For UI-driven Android checks, an agent still needs an emulator it can start, reset, control, and inspect. That work continues to use adb, Emulator CLI, ordinary tests, and web previews.

An agent does not gain capabilities beyond the tools it can call. It remains bounded by the emulator’s capabilities and blind spots. Checks involving hardware, performance limits, OEM software, default apps, or real connectivity still need physical phones.

What this looks like in daily work

I stay in the web preview while a change touches only the UI or shared web logic. When it reaches the Android shell, WebView, plugins, or lifecycle, I start an AVD with a Google APIs image from one of my script templates. I use a Play Store image only when I need the store itself or its release-signed restrictions.

An Android phone remains beside my laptop for hardware, performance, OEM software, default apps, real connectivity, and release checks. The AVD covers the repeatable daily loop. The phone covers behavior I cannot reproduce there.

Browse all writing →