Running Android Locally with Waydroid
How TecunHuman uses Waydroid and a nested Weston session to run and test Godot Android builds locally on Linux.

I recently needed a convenient way to test an Android build of one of my Godot projects without continually copying the APK to a phone.
For quick development builds, I wanted something that could run locally on my Linux desktop and still behave like Android. I ended up using Waydroid, which runs a full Android system in a Linux container.
My desktop setup needed one extra piece: Waydroid expects a Wayland session, so I used Weston, a small Wayland compositor, in a window. That gave Waydroid the Wayland display it needed without requiring me to change my normal desktop session.
Here is the complete workflow I used to install Waydroid, start Android inside Weston, install a Godot APK, and remove an older build when necessary.
Installing Waydroid and Weston
These commands are for Ubuntu, Debian, and related distributions. The official Waydroid installation guide includes the current repository setup instructions and directions for other Linux distributions.
After adding the Waydroid repository, I installed Waydroid and Weston:
sudo apt install waydroid weston -yWaydroid downloads and configures its Android image during initialization. I chose the GAPPS image because I wanted Google apps and services available:
sudo waydroid init -s GAPPSGAPPS is optional. If a project does not depend on Google Play services, the default vanilla image may be enough:
sudo waydroid initChoose the image you want the first time you initialize Waydroid. Replacing an existing image is a reset operation and may remove the Android data already stored in the container.
I then enabled and started the container service:
sudo systemctl enable --now waydroid-containerGiving Waydroid a Wayland Display
Because I was not already running the desktop in a Wayland session, I launched Weston as a nested compositor:
weston --xwaylandThis opens a Weston desktop in its own window. Keep that process running while using Waydroid.
Weston prints the name of the Wayland display it creates. On my machine it was wayland-1, so I launched the full Android interface with:
WAYLAND_DISPLAY=wayland-1 waydroid show-full-uiThe socket name is not guaranteed to be wayland-1. If that command cannot connect to the display, check the Weston terminal output or list the available sockets:
ls "$XDG_RUNTIME_DIR"/wayland-*Then use the appropriate name as WAYLAND_DISPLAY.
Waydroid can also be started in two explicit steps. This is useful when diagnosing whether a problem is in the Android session or only in the UI:
waydroid session start
WAYLAND_DISPLAY=wayland-1 waydroid show-full-uiThe session command should be run as the normal desktop user, not with sudo.
Choosing a Useful Window Size
For testing a phone layout, I can give the nested Weston window a portrait-oriented size:
weston --xwayland --width=720 --height=1280I also experimented with Waydroid’s Android display properties:
waydroid prop set persist.waydroid.width 720Waydroid properties generally take effect after restarting the session:
waydroid session stop
waydroid session startSetting the Weston window size was the simpler option for my workflow because it made the entire nested desktop resemble a phone display.
Installing a Godot APK
Once Android was running, I installed my exported Godot project directly from the terminal:
waydroid app install ./quetzalcoatl.apkFor more information when an installation failed, I enabled verbose output and sent the details to the terminal:
waydroid --details-to-stdout -v app install ./quetzalcoatl.apkThat version is especially useful during development because a normal install command may not show enough information to explain the problem.
To confirm that the application was installed, I listed the Waydroid applications and filtered the result:
waydroid app list | grep -i quetzalcoatlIf I know the Android package name, I can launch it directly:
waydroid app launch com.example.quetzalcoatlThe application also appears in Waydroid’s Android launcher.
One important limitation is that the APK must support the architecture used by the Waydroid image. On a typical x86_64 Linux computer, an APK containing only ARM native libraries will not run without an additional translation layer. For Godot projects, I make sure the Android export includes an architecture compatible with the environment I am testing.
Removing an Older Build
During development, Android may refuse an update if the new APK was signed with a different key, uses an incompatible version, or otherwise conflicts with the installed package.
Waydroid provides an app removal command when I know the package name:
waydroid app remove com.example.quetzalcoatlWhen I needed to work directly through Android’s package manager, I used:
sudo waydroid shell pm uninstall com.example.quetzalcoatlAfter uninstalling the old package, I could install the new APK again:
waydroid --details-to-stdout -v app install ./quetzalcoatl.apkThe value passed to remove, launch, or pm uninstall is the Android package ID, not the APK filename or the human-readable application name. In a Godot project, this corresponds to the package identifier configured in the Android export preset.
A Few Useful Diagnostic Commands
These were the commands I found most useful when something was not working:
sudo systemctl status waydroid-container
waydroid app list
waydroid log
sudo waydroid shellThe first checks the Linux container service. waydroid app list confirms what Android thinks is installed, waydroid log shows Waydroid’s log output, and the shell provides direct access to Android commands such as pm.
If an application checks specifically for a Wi-Fi connection, Waydroid can also make selected packages see its network connection as Wi-Fi. To apply that behavior to every package:
waydroid prop set persist.waydroid.fake_wifi '*'That is not needed for most applications, so I would only enable it when a particular app requires it.
My Everyday Workflow
After the initial installation, my normal testing loop is short:
- Start Weston with
weston --xwayland. - Open Android with
WAYLAND_DISPLAY=wayland-1 waydroid show-full-ui. - Export the Android APK from Godot.
- Install it with
waydroid --details-to-stdout -v app install ./quetzalcoatl.apk. - Launch the app and test it.
- Remove the installed package if Android will not accept the next development build.
Waydroid does not replace testing on real Android hardware. Physical devices still matter for touch input, sensors, performance, graphics-driver differences, screen cutouts, and device-specific behavior.
What it does provide is a very fast local feedback loop. For testing whether a build installs, starts, connects to services, and handles an Android-sized display, I can stay on the development machine and repeat the process as often as necessary.
That has made Android testing feel much closer to running an ordinary desktop build, while still exercising the actual Android export of the project.