# Android Emulators

Run Android emulators with hardware acceleration on Namespace runners.

Namespace runners support hardware-accelerated Android virtualization using KVM. This enables fast Android emulator testing without the performance penalty of software emulation.

KVM-backed Android emulators are currently supported on Linux AMD64 runners (`linux/amd64`). No additional KVM setup is required when using that platform.

## Getting started

### 1. Create a runner profile

We recommend using a dedicated profile for Android Emulator workflows.

Go to your [runner profiles](https://cloud.namespace.so/workspace/actions/profiles) and create a profile named `namespace-profile-android` with:

* Linux AMD64 ( `linux/amd64` )
* Enough resources for your emulator, `4 vCPU x 8 GB RAM` is a good starting point
* Caching enabled to cache Gradle dependencies.

Then use the created profile as your runs-on label:

```yaml theme={null}
jobs:
  android-tests:
    runs-on: namespace-profile-android
```

### 2. Set up caching

Use [`namespacelabs/nscloud-cache-action`](/content/docs/reference/github-actions/nscloud-cache-action/index.html) to cache Gradle dependencies for faster builds:

```yaml theme={null}
- name: Set up Gradle cache
  uses: namespacelabs/nscloud-cache-action@v1
  with:
    cache: gradle
```

### 3. Set up JDK and Android SDK

Use `actions/setup-java` and `android-actions/setup-android` to install the required tooling:

```yaml theme={null}
- name: Set up JDK
  uses: actions/setup-java@v4
  with:
    distribution: temurin
    java-version: 17

- name: Set up Android SDK
  uses: android-actions/setup-android@v3
```

### 4. Run the emulator

Start an emulator and run your tests, for example by using the `reactivecircus/android-emulator-runner` action:

```yaml theme={null}
- name: Run Android tests
  uses: reactivecircus/android-emulator-runner@v2
  with:
    api-level: 30
    arch: x86_64
    script: ./gradlew connectedCheck
```

## Full example

Here's a complete workflow for running Android tests:

```yaml theme={null}
name: Android Tests

on:
  push:
    branches: [main]
  pull_request:

jobs:
  android-tests:
    runs-on: namespace-profile-android
    steps:
      - name: Checkout repository
        uses: namespacelabs/nscloud-checkout-action@v7

- name: Set up Gradle cache
        uses: namespacelabs/nscloud-cache-action@v1
        with:
          cache: gradle

- name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: 17

- name: Set up Android SDK
        uses: android-actions/setup-android@v3

- name: Run Android tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: 30
          arch: x86_64
          script: ./gradlew connectedCheck
```

## Gradle build cache

In addition to caching Gradle dependencies with Cache Volumes, you can also use Namespace's [Gradle build cache](/content/docs/integrations/gradle.md) to share build outputs across runs. This is complementary to caching dependencies — while Cache Volumes store downloaded dependencies, the Gradle build cache stores compilation outputs and task results.

To use both in your workflow:

```yaml theme={null}
- name: Set up Gradle dependency cache
  uses: namespacelabs/nscloud-cache-action@v1
  with:
    cache: gradle

- name: Set up Gradle build cache
  run: nsc cache gradle setup --init-gradle /tmp/init.gradle

- name: Run Android tests
  uses: reactivecircus/android-emulator-runner@v2
  with:
    api-level: 30
    arch: x86_64
    script: ./gradlew --init-script=/tmp/init.gradle connectedCheck
```

## Related documentation

* [Nested Virtualization](/content/docs/architecture/compute/nestedvirt/index.html) — Platform support for `/dev/kvm`
* [Gradle integration](/content/docs/integrations/gradle.md) — Gradle build caching
* [Machine Shapes](/content/docs/architecture/compute/machine-shapes.md) — Available machine configurations
* [Caching](/content/docs/solutions/github-actions/caching.md) — Speed up builds with cache volumes
