Created
June 17, 2026 21:34
-
-
Save aznoisib/d6f7ead962e030528f6cf05f480f1205 to your computer and use it in GitHub Desktop.
Android Development Environment Setup (Without KVM)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $ mkdir -p /data/android-workspace && cat > /data/android-workspace/README.md << 'EOF' | |
| # Android Development Environment Setup (Without KVM) | |
| ## Overview | |
| This guide documents how to set up a complete Android development environment on a machine without KVM hardware virtualization support, using Redroid (Remote Android) containerized solution. | |
| **Tested on:** Linux 6.8.0-71-generic, Docker, Android SDK 36.6.11 | |
| ## Prerequisites | |
| - Linux host (Ubuntu/Debian recommended) | |
| - Docker installed and running | |
| - Android SDK command-line tools | |
| - Root access (for kernel module loading) | |
| ## Step-by-Step Setup | |
| ### 1. Load Required Kernel Modules | |
| The host kernel needs `binderfs` support for Android IPC: | |
| ```bash | |
| # Check if binder module exists | |
| find /lib/modules/$(uname -r) -name "*binder*" | |
| # Load binder module with all device types | |
| modprobe binder_linux devices="binder,hwbinder,vndbinder" | |
| # Verify binderfs is available | |
| mount -t binder binder /dev/binderfs | |
| ls -la /dev/binderfs | |
| ``` | |
| Expected output: | |
| ``` | |
| binder_linux 233472 0 | |
| crw------- 1 root root 241, 1 binder | |
| crw------- 1 root root 241, 0 binder-control | |
| crw------- 1 root root 241, 2 hwbinder | |
| crw------- 1 root root 241, 3 vndbinder | |
| ``` | |
| ### 2. Install Android SDK Components | |
| ```bash | |
| # Set environment variables | |
| export ANDROID_HOME=/data/android-sdk | |
| export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/cmdline-tools/latest/bin | |
| # Install required SDK packages | |
| sdkmanager "platform-tools" | |
| sdkmanager "build-tools;34.0.0" | |
| sdkmanager "platforms;android-34" "platforms;android-35" | |
| ``` | |
| ### 3. Start Redroid Container | |
| ```bash | |
| # Remove any existing containers | |
| docker rm -f redroid 2>/dev/null | |
| # Start Redroid with memfd (bypasses missing ashmem module) | |
| docker run -d --rm --privileged \ | |
| -v ~/redroid-data:/data \ | |
| -p 5559:5555 \ | |
| --name redroid \ | |
| redroid/redroid:14.0.0-latest \ | |
| androidboot.use_memfd=true \ | |
| ro.secure=0 | |
| # Wait for boot (takes ~2-3 minutes) | |
| sleep 120 | |
| ``` | |
| ### 4. Connect and Verify | |
| ```bash | |
| # Connect ADB | |
| adb connect localhost:5559 | |
| adb devices | |
| # Verify boot complete | |
| adb -s localhost:5559 shell getprop sys.boot_completed | |
| # Should return: 1 | |
| # Check Android version | |
| adb -s localhost:5559 shell getprop ro.build.version.release | |
| # Should return: 14 | |
| ``` | |
| ### 5. Configure Development Environment | |
| ```bash | |
| # Enable developer options | |
| adb -s localhost:5559 shell settings put global development_settings_enabled 1 | |
| # Enable stay awake while charging | |
| adb -s localhost:5559 shell settings put global stay_on_while_plugged_in 3 | |
| # Set screen timeout (30 minutes) | |
| adb -s localhost:5559 shell settings put system screen_off_timeout 1800000 | |
| # Disable animations for faster testing | |
| adb -s localhost:5559 shell settings put global window_animation_scale 0 | |
| adb -s localhost:5559 shell settings put global transition_animation_scale 0 | |
| adb -s localhost:5559 shell settings put global animator_duration_scale 0 | |
| # Set timezone | |
| adb -s localhost:5559 shell setprop persist.sys.timezone Asia/Shanghai | |
| ``` | |
| ## Key Technical Details | |
| ### Why This Works | |
| 1. **Redroid vs Android Emulator**: Redroid runs Android userspace directly on the host kernel, avoiding QEMU emulation entirely | |
| 2. **binderfs**: Modern kernel feature for Android IPC, replaces legacy `/dev/binder` | |
| 3. **memfd**: Alternative to ashmem for shared memory, available in kernel 6.8+ | |
| 4. **No KVM Required**: Redroid doesn't use virtualization - it's containerized Android | |
| ### Kernel Requirements | |
| - **binderfs**: Available in kernel 5.0+ with `CONFIG_ANDROID_BINDERFS=y` | |
| - **memfd**: Available via `CONFIG_MEMFD_CREATE=y` (standard in modern kernels) | |
| - **ashmem**: NOT required when using `androidboot.use_memfd=true` | |
| ### Common Issues and Solutions | |
| | Issue | Solution | | |
| |-------|----------| | |
| | `modprobe: FATAL: Module ashmem_linux not found` | Use `androidboot.use_memfd=true` flag | | |
| | Container exits immediately | Ensure `--privileged` flag and binderfs mounted | | |
| | ADB device offline | Wait longer for boot (2-3 min), check container logs | | |
| | Port 5555 already in use | Use different port mapping (e.g., `-p 5559:5555`) | | |
| ## Verification Checklist | |
| - [ ] binderfs mounted at `/dev/binderfs` | |
| - [ ] Redroid container running (`docker ps`) | |
| - [ ] ADB connected (`adb devices` shows `localhost:5559 device`) | |
| - [ ] `sys.boot_completed` returns `1` | |
| - [ ] Package manager accessible (`adb shell pm list packages`) | |
| - [ ] Screenshots work (`adb exec-out screencap -p > screen.png`) | |
| ## Quick Start Script | |
| ```bash | |
| #!/bin/bash | |
| # setup-android.sh - Complete setup script | |
| set -e | |
| echo "=== Loading Kernel Modules ===" | |
| modprobe binder_linux devices="binder,hwbinder,vndbinder" | |
| mount -t binder binder /dev/binderfs 2>/dev/null || true | |
| echo "=== Starting Redroid ===" | |
| docker rm -f redroid 2>/dev/null || true | |
| docker run -d --rm --privileged \ | |
| -v ~/redroid-data:/data \ | |
| -p 5559:5555 \ | |
| --name redroid \ | |
| redroid/redroid:14.0.0-latest \ | |
| androidboot.use_memfd=true | |
| echo "=== Waiting for Boot ===" | |
| for i in {1..6}; do | |
| sleep 30 | |
| if adb -s localhost:5559 shell getprop sys.boot_completed 2>/dev/null | grep -q 1; then | |
| echo "Boot complete!" | |
| break | |
| fi | |
| echo "Waiting... ($i/6)" | |
| done | |
| echo "=== Configuring Device ===" | |
| adb connect localhost:5559 | |
| adb -s localhost:5559 shell settings put global development_settings_enabled 1 | |
| adb -s localhost:5559 shell settings put global window_animation_scale 0 | |
| adb -s localhost:5559 shell settings put global transition_animation_scale 0 | |
| adb -s localhost:5559 shell settings put global animator_duration_scale 0 | |
| echo "=== Setup Complete ===" | |
| adb devices | |
| ``` | |
| ## Session Recovery | |
| If the session was interrupted: | |
| ```bash | |
| # Check container status | |
| docker ps | grep redroid | |
| # Restart if needed | |
| docker rm -f redroid | |
| # Run step 3 again | |
| # Reconnect ADB | |
| adb kill-server | |
| adb connect localhost:5559 | |
| ``` | |
| ## Resources | |
| - Redroid Documentation: https://github.com/remote-android/redroid-doc | |
| - Android SDK: https://developer.android.com/studio#downloads | |
| - Kernel Modules: https://github.com/remote-android/redroid-modules | |
| --- | |
| **Last Updated:** 2026-06-18 | |
| **Tested Configuration:** Linux 6.8.0-71-generic, Docker, Redroid 14.0.0, Android SDK 36.6.11 | |
| **Status:** ✅ Working | |
| EOF | |
| echo "README.md created successfully" | |
| cat /data/android-workspace/README.md | wc -l | |
| README.md created successfully | |
| 214 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment