OFFSET偏移
← 文章目录OFFSET / FIELD NOTESNO. 143

Waydroid 安装与基础设置

检查 Wayland、内核和图形条件,再安装镜像并逐层验证启动。

所在专题Waydroid ↗
约 32 分钟阅读开始阅读

适用范围与操作前提#

命令和输出使用通用示例。内核、镜像、包与服务版本会影响具体行为,阅读时应结合所用版本的文档核对。

修改容器、镜像、挂载和防火墙前先备份 Android 数据并停止相关会话;带删除或强制停止的示例可能丢失数据。NixOS 的系统与用户环境配置应通过 Nix 管理,通用 Linux 的 apt/pacman、直接写 /etc 和 pip 安装段落不用于 NixOS 宿主。重建的 build、test、switch 与启动后的功能验证是不同阶段。

本文涵盖环境依赖检查、多发行版安装对比、waydroid init 镜像下载流程、容器首次启动与端到端验证。


环境要求#

Waydroid 不是模拟器,不是虚拟机——它通过 Linux namespace 隔离 + binder 直通让 Android 用户空间直接跑在宿主内核上。这带来了极低的开销,但也对宿主环境提出了刚性约束。具体要求要按组件判断:容器启动、图形会话和应用兼容性是不同验收层。

Wayland 会话:硬性要求

Waydroid 必须在 Wayland 会话下运行,不原生支持 X11。这是因为 Android 图形栈直接通过 wayland-client 协议渲染到宿主 compositor,绕过 X11 中间层。

# 检查当前图形会话协议
echo $XDG_SESSION_TYPE
# 期望输出: wayland

# 如果输出 x11,检查当前登录管理器是否支持 Wayland
loginctl show-session $(loginctl | grep $(whoami) | awk '{print $1}') -p Type

X11 用户怎么办 如果桌面环境仍运行在 X11 上(如某些旧版 GNOME、Xfce、MATE),有以下两种方案:

  1. 切换到 Wayland 会话:在登录管理器(SDDM/GDM/LightDM)中选择带 "Wayland" 后缀的会话选项。这是推荐方案。

  2. 嵌套 Wayland compositor:在 X11 内启动一个嵌套的 Wayland compositor,然后在其中运行 Waydroid。常用工具:

    • cage — 极简 kiosk-style Wayland compositor,仅支持单个全屏应用
    • weston — 功能完整的参考 compositor,支持嵌套模式
    # 使用 weston 嵌套模式启动一个最小 Wayland 环境
    # 终端 A: 启动 weston
    weston --width=1280 --height=720 &
    # 终端 B: 在 weston 内启动 Waydroid
    WAYLAND_DISPLAY=wayland-1 waydroid show-full-ui

嵌套 compositor 方案会引入额外性能开销,仅作临时过渡。

CPU 指令集要求

x86_64 架构下,Waydroid 的 Android 系统镜像为 x86_64 构建,但某些关键组件(如 libhoudini ARM 转译引擎)依赖特定 SIMD 指令集。

# 检查必需指令集
grep -o -E 'ssse3|sse4_1|sse4_2' /proc/cpuinfo | sort -u

# 转译组件可能要求其中部分指令,不是所有 Waydroid 场景的统一要求:
# ssse3
# sse4_1
# sse4_2

# 一行版本:所有指令都存在则返回 3
grep -o -E 'ssse3|sse4_1|sse4_2' /proc/cpuinfo | sort -u | wc -l
# 期望输出: 3

内核模块

检查当前版本需要的 Binder、共享内存、PSI 和网络支持;不是每个名称都对应可加载内核模块。

binder / rust_binder

binder 是 Android 的核心 IPC 机制。Binder 有 C 实现和较新的 Rust 实现;模块名称与是否提供取决于具体内核/发行版,不能根据 5.7 或 6.7 的版本号推断替换关系。常见 C 实现模块名为 binder_linux。

# 检查 binder 或 rust_binder 模块是否可用
modprobe --dry-run binder_linux 2>&1 || modprobe --dry-run rust_binder 2>&1

# 如果上述命令报 "modprobe: FATAL: Module binder not found"
# 说明内核未编译 binder 支持,需重新编译内核或更换支持 Android 的内核

# 检查模块是否已加载
lsmod | grep -E 'binder'

binder vs rust_binder

模块 内核版本 配置选项 特点
binder_linux 由具体内核提供 CONFIG_ANDROID_BINDER_IPC C 实现
rust_binder 核对具体发行版与版本 依内核配置 Rust 实现

现代发行版(Ubuntu 22.04+、Fedora 37+、Arch 当前)的内核通常已包含二者之一。NixOS 需手动配置,详见 03 NixOS 深度集成。

PSI (Pressure Stall Information)

PSI 是内核资源压力监控基础设施。Waydroid 的 lxc-monitord 依赖 PSI 来感知容器资源压力。先检查 CONFIG_PSI 与 /proc/pressure/;当 PSI 默认禁用时,可通过 psi=1 启用。它同时涉及编译配置与启动策略,不是 Binder 协议本身的依赖。

# 检查 PSI 是否已启用
cat /proc/pressure/cpu
# 如果文件存在且有输出,说明 PSI 已启用
# 如果报 "No such file or directory",说明未启用

# 检查内核启动参数中是否有 psi=1
cat /proc/cmdline | grep -o 'psi=1'

如果 psi=1 未设置,需要修改 bootloader 配置:

Bootloader 配置文件 方法
GRUB /etc/default/grub GRUB_CMDLINE_LINUX 行追加 psi=1,然后 sudo update-grub 或 sudo grub-mkconfig -o /boot/grub/grub.cfg
systemd-boot /boot/loader/entries/*.conf 在 options 行追加 psi=1
NixOS configuration.nix boot.kernelParams = ["psi=1"];

psi=1 缺失是最常见的安装失败原因 如果 waydroid container start 后出现 lxc-monitord[xxx]: Failed to open /proc/pressure/cpu 或容器立刻退出,应查看实际失败日志并检查 /proc/pressure/,没有统计证据可以给此原因分配固定概率。

IPv6 必须启用

Waydroid 容器内部依赖 IPv6 进行某些系统服务的通信,即使宿主机不使用 IPv6 接入外部网络。

# 检查 IPv6 是否启用
sysctl net.ipv6.conf.all.disable_ipv6
# 期望输出: net.ipv6.conf.all.disable_ipv6 = 0

# 如果为 1,临时启用
sudo sysctl net.ipv6.conf.all.disable_ipv6=0

# 永久启用:确保 /etc/sysctl.conf 或 /etc/sysctl.d/ 中没有
# net.ipv6.conf.all.disable_ipv6 = 1

GPU 推荐

Waydroid 的 GPU 加速能力因厂商而异,直接影响 Android 应用的图形性能。

GPU 厂商 支持度 驱动 备注
Intel 常见支持路径 i915/xe + Mesa 镜像、驱动与实际渲染需验证
AMD 常见支持路径 amdgpu + Mesa 不保证固定版本起一概可用
NVIDIA (专有驱动) 上游选择器过滤 nvidia 可显式使用官方文档的软件渲染方案
NVIDIA (Nouveau) 需实际验证 nouveau + Mesa 当前映射包含 nouveau,不能保证特定 GPU/应用兼容
虚拟机 (VM) 部分 virtio-gpu / vmwgfx 取决于宿主 GPU 直通或虚拟化 GPU 配置

NVIDIA 专有驱动的现实 现代 NVIDIA 驱动支持 GBM;所查 Waydroid 仍过滤 nvidia 驱动,因为整套 Android 图形集成不能由宿主 GBM 支持单独保证。无可用硬件节点时的软件路径也应检查镜像与配置,下面只是常见负载观察,不能视为性能承诺:

  • 轻量应用(微信、抖音)尚可接受
  • 3D 游戏几乎不可玩
  • 视频播放可能出现明显卡顿

NVIDIA 用户可尝试 04 GPU 与硬件加速 中的实验性方案。

LXC 版本要求

Waydroid 依赖 LXC >= 4.0,推荐 LXC >= 5.0。

# 检查 LXC 版本
lxc-info --version
# 期望输出: 5.0.x 或 4.0.x

# 同时检查 Python LXC 绑定
python3 -c "import lxc; print(lxc.__version__)"

多发行版安装对比#

Waydroid 在不同 Linux 发行版上的安装方式差异显著——从社区仓库的一键安装到需要手动配置内核模块。下表给出各主流发行版的完整安装路径。

维度 Ubuntu / Debian Arch Linux NixOS Fedora
包名 waydroid waydroid pkgs.waydroid-nftables (推荐) waydroid
安装源 官方 curl 脚本添加 apt 源 extra 仓库 nixpkgs virtualisation.waydroid Fedora 官方仓库(旧教程使用过 COPR)
安装命令 apt install waydroid pacman -S waydroid 声明式 enable = true dnf copr enable + dnf install
初始化命令 sudo waydroid init sudo waydroid init sudo waydroid init sudo waydroid init
容器服务名 waydroid-container waydroid-container waydroid-container waydroid-container
内核模块 内核自带 binder 内核自带 binder 需单独配置 boot.kernelModules 内核自带 binder
维护者 官方 (Waydroid team) Arch 官方仓库 nixpkgs maintainers aleasto (COPR)

Ubuntu / Debian

Ubuntu 和 Debian 优先通过官方 apt 仓库安装,以获取最新版本和更新。

# 1. 添加官方 apt 仓库并安装 GPG 密钥(需要 curl)
#    该脚本自动检测发行版版本并配置对应的 apt source
curl -s https://repo.waydro.id | sudo bash

# 2. 安装 Waydroid 主程序
sudo apt install waydroid

# 3. 可选:安装 Google Play Services 支持
# GAPPS 通过 waydroid init -s GAPPS 选择,不假定有 waydroid-gapps 包
文件 路径
apt source list /etc/apt/sources.list.d/waydroid.list
GPG key /usr/share/keyrings/waydroid.gpg
主二进制 /usr/bin/waydroid
systemd unit /usr/lib/systemd/system/waydroid-container.service

Arch Linux

Waydroid 位于 Arch extra 仓库,无需额外添加源。

# 安装 Waydroid(含所有运行时依赖)
sudo pacman -S waydroid

# 内核模块:Arch 的 linux/linux-lts 内核默认包含 binder
# 确认 binder 已加载:
lsmod | grep binder

# 如果需要额外工具
yay -S waydroid-image       # 第三方来源:先确认包仍存在; 预下载的镜像(可选,跳过 init 下载)
yay -S waydroid-script-git  # 第三方来源:先确认包仍存在; 额外辅助脚本(可选)

Arch bwrap 权限问题 某些 Arch 安装中,bubblewrap (bwrap) 可能因内核 unprivileged user namespaces 限制而失败:

# 检查是否受限
sysctl kernel.unprivileged_userns_clone
# 如果为 0,需要设为 1:
sudo sysctl kernel.unprivileged_userns_clone=1

NixOS

NixOS 的 Waydroid 集成通过声明式配置实现,是所有发行版中最特殊的一种。核心要点:

# /etc/nixos/configuration.nix 或 flake 配置
{
  virtualisation.waydroid = {
    enable = true;
    # package = pkgs.waydroid-nftables;  # 默认随 networking.nftables.enable 选择,不固定
  };

  # 26.05 模块已经配置 psi=1 并检查 Binder/BinderFS/MEMFD
  # 自定义内核另行检查实际支持,不盲目重复指定模块
}

应用配置:

sudo nixos-rebuild switch
sudo waydroid init

NixOS 章节将在 03 号子文档全面展开 NixOS 的 Waydroid 集成涉及模块选项(virtualisation.waydroid.*)、nftables 网络规则、waydroid-helper 工具、命令式与声明式操作边界等主题。以上仅给出最简配置,完整说明请参阅 03 NixOS 深度集成。

Fedora

Fedora 当前官方安装说明使用发行版仓库,旧 COPR 方案只属于历史参考。

# 启用 COPR 仓库
# 当前常规安装不需要启用旧 COPR

# 安装 Waydroid
sudo dnf install waydroid

# SELinux 可能需要调整(如遇权限问题)
# 先查看 SELinux AVC 日志并修正标签/策略,不默认关闭 SELinux
# 永久:需编写 SELinux 策略模块(超出本文范围)

waydroid init 详解#

waydroid init 是整个安装流程的核心步骤——它负责下载 Android 系统镜像、验证完整性、并在宿主机上创建容器所需的文件系统结构。

基本用法

# 最简初始化:下载标准 LineageOS 镜像(无 Google 服务)
sudo waydroid init

# 带 Google Play Services 的初始化
sudo waydroid init -s GAPPS

# 强制重新下载(即使已有镜像)
sudo waydroid init -f # 强制初始化;先核对当前状态与备份

# 指定下载渠道
sudo waydroid init -c https://ota.waydro.id/system  # 默认渠道
参数 全称 作用
无 — 下载 x86_64 LineageOS 系统镜像(Android 13),无 Google 服务
-s GAPPS --system_type GAPPS 下载预装 Google Play Services、Play Store、Gboard 等的 GAPPS 变体
-f --force 强制初始化/自定义镜像处理;不保证每次重新下载,也不自动等于清空用户数据
-c URL --system_channel URL 指定系统 OTA URL;vendor 渠道另用 -v

镜像下载详情

waydroid init 从 sourceforge.net 下载两个核心镜像文件,约 700~1000 MB,取决于是否选择 GAPPS 变体。

文件 大小(标准) 大小(GAPPS) 内容
system.img ~500 MB ~680 MB Android 系统分区:LineageOS 主线 + GAPPS 变体增项(Play Services, Play Store, Gboard, WebView 等)
vendor.img ~300 MB ~300 MB 硬件适配层(HAL):GPU 驱动、音频 HAL、传感器 shim、Wayland gralloc

下载完成后,镜像被存储到 /var/lib/waydroid/ 目录:

# 查看已下载的镜像
ls -lh /var/lib/waydroid/images/
# 期望输出:
# -rw-r--r-- 1 root root  xxxM ... system.img
# -rw-r--r-- 1 root root  xxxM ... vendor.img

底层流程

waydroid init 执行时,内部经历了以下步骤:

graph TD
    A["waydroid init 启动"] --> B{本地已有镜像?}
    B -->|否,或指定 -f| C["从 SourceForge 下载<br/>system.img + vendor.img"]
    B -->|是| D[跳过下载]
    C --> E["校验 SHA256 哈希<br/>确保镜像完整性"]
    D --> E
    E --> F["创建 /var/lib/waydroid/ 目录树"]
    F --> G["挂载 system.img<br/>按实际镜像格式与 overlay 布局"]
    G --> H["创建 /var/lib/waydroid/waydroid_base.prop"]
    H --> I["写入 build.prop 属性<br/>(ro.waydroid.version 等)"]
    I --> J["生成 LXC 配置文件<br/>/var/lib/waydroid/lxc/waydroid/config"]
    J --> K["init 完成"]

文件系统结构 Waydroid 使用 overlayfs 将只读的 system.img 与可写的数据层叠加:

  • 系统镜像通常位于 /var/lib/waydroid/images/system.img,先挂载为目录才可作为 overlay 下层
  • Android /data 使用用户数据目录;不是系统/vendor overlay 的通用 upperdir
  • 这意味着系统镜像的每次 OTA 升级不会影响用户数据和已安装应用

镜像存储位置总览

路径 内容 权限
/var/lib/waydroid/images/system.img LineageOS 系统分区镜像 root:root (644)
/var/lib/waydroid/images/vendor.img 硬件适配层镜像 root:root (644)
/var/lib/waydroid/waydroid_base.prop Android 系统属性基线 root:root (644)
/var/lib/waydroid/lxc/waydroid/config LXC 容器运行时配置 root:root (644)
~/.local/share/waydroid/data/ 用户数据、已安装的 APK 当前用户
~/.local/share/applications/waydroid.*.desktop Android 应用的桌面启动器条目 当前用户

首次启动与验证#

镜像下载完成后,按以下顺序启动 Waydroid 并执行端到端验证。

启动容器服务

Waydroid 的运行分为两层:容器守护进程(systemd 服务,管理 LXC 容器生命周期)和Android 会话(用户空间,管理 Android 运行时)。

# 启动容器服务并设为开机自启
sudo systemctl enable --now waydroid-container

# 检查服务状态
sudo systemctl status waydroid-container

# 期望输出关键行:
# Active: active (running) since ...
# CGroup: /system.slice/waydroid-container.service
#         ├─ /usr/bin/python3 /usr/bin/waydroid -w container start
#         └─ /usr/bin/lxc-start -F -n waydroid -- /init

容器服务的角色 waydroid-container.service 以 root 权限运行,负责:

  • 启动 lxc-start 引导 Android init 进程
  • 管理 binder 设备节点 (/dev/binder)
  • 设置 namespace 隔离和 cgroup 资源限制
  • 挂载 Android 系统分区 overlay

Android 用户空间的运行则由普通用户通过 session bus 控制,不涉及 root 权限。

启动 Android 会话

容器运行后,Android 内部还需要启动会话管理器(相当于 Android 的 "用户登录")。

# 启动 Waydroid 会话
waydroid session start

# 等待日志中出现 "Android with user 0 is ready"
# 这表示 Android 服务框架(system_server, SurfaceFlinger 等)全部就绪

会话启动过程中,可以用另一个终端实时监控:

# 跟踪 Waydroid 日志(容器 + 会话)
waydroid log # -c 是清除日志,不是跟踪标志

# 或者只看会话层日志
journalctl -u waydroid-container -b

打开 Android 桌面

会话就绪后,启动完整的 Android 桌面环境:

waydroid show-full-ui

这会打开一个窗口,显示完整的 LineageOS 桌面(含启动器、状态栏、导航栏),与一台原生 Android 设备别无二致。

健康检查命令

命令 作用 期望结果
waydroid status 检查容器和会话状态 Session: RUNNING + Container: RUNNING
waydroid app list 列出已安装的 Android 应用 至少显示 com.android.settings、com.android.launcher3 等系统应用
sudo waydroid shell 进入 Android 容器 shell 看到 waydroid:/ # 提示符,可以执行 getprop、pm list packages 等 Android 命令
waydroid log 查看运行日志 逐行输出 Wayland/EGL/binder 等子系统的运行信息

具体使用示例:

# 1. 状态检查
$ waydroid status
Session:        RUNNING
Container:      RUNNING
Vendor type:    MAINLINE
Session user:   0 (0)
Wayland display: wayland-1

# 2. 列出已安装应用
$ waydroid app list
Name: Settings, package: com.android.settings
Name: Trebuchet, package: com.android.launcher3
...

# 3. 进入容器 shell
$ sudo waydroid shell
waydroid:/ # getprop ro.build.version.release
13
waydroid:/ # pm list packages | head -5
package:com.android.settings
...
waydroid:/ # exit

应用管理速查

# 通过包名启动应用
waydroid app launch com.android.settings          # 打开设置
waydroid app launch com.android.launcher3         # 打开启动器

# 安装 APK 文件
waydroid app install /path/to/application.apk     # 安装单个 APK

# 通过 Google Play 安装(GAPPS 变体)
waydroid app launch com.android.vending           # 启动 Play Store
# 然后在 Play Store 中正常搜索安装

# 为 Android 应用创建桌面快捷方式
# 安装 APK 后,waydroid 会自动在 ~/.local/share/applications/ 下
# 生成 waydroid.<package>.desktop 文件
ls ~/.local/share/applications/waydroid.*.desktop

设置 Android 系统属性

# 查看当前属性
waydroid prop get persist.waydroid.width
waydroid prop get persist.waydroid.height

# 设置属性(影响 Android 设备行为)
waydroid prop set persist.waydroid.width 720        # 设置窗口宽度
waydroid prop set persist.waydroid.height 1280       # 设置窗口高度
waydroid prop set persist.waydroid.fake_wifi "com.example.app"    # 伪装 Wi-Fi 连接
waydroid prop set persist.waydroid.multi_windows true # 启用多窗口模式

# 部分属性修改后需重启会话才能生效
waydroid session stop
waydroid session start

停止 Waydroid

# 先停止 Android 会话
waydroid session stop

# 再停止容器服务
sudo systemctl stop waydroid-container

# 完全清理(停止会话 + 停止容器 + 释放资源)
waydroid session stop && sudo systemctl stop waydroid-container

停止顺序 必须先停止会话再停止容器。如果直接停容器而会话仍在运行,D-Bus 会话管理器会反复尝试重连,导致日志刷屏和资源占用异常。

启动故障排查速查表

症状 可能原因 检查命令
container is not running binder 模块未加载 lsmod | grep binder
容器启动后立即退出 psi=1 未设置 cat /proc/cmdline | grep psi=1
Failed to connect to wayland X11 会话或 WAYLAND_DISPLAY 无效 echo $XDG_SESSION_TYPE
Wayland connection failed Wayland compositor 拒绝连接 echo $WAYLAND_DISPLAY + 确认 compositor 运行
Failed to open /dev/binder binder 设备权限不足 ls -la /dev/binder*
网络不可用(无 IPv4) waydroid0 网桥未创建 ip link show waydroid0
Play Protect 认证失败 GAPPS 变体未注册设备 ID 见 07 故障排查
GPU 渲染失败,黑屏 NVIDIA 专有驱动 waydroid log | grep -i gpu

调试模式 遇到启动问题时,waydroid 提供了详细的调试输出:

# 前台运行容器(日志直接输出到终端)
sudo waydroid --details-to-stdout container start

# 前台运行会话
waydroid --details-to-stdout session start

# 结合 journalctl 查看系统日志
sudo journalctl -u waydroid-container -f

小结#

执行后的验收应逐项确认:

  • Wayland 会话环境确认
  • 所有必需内核模块加载(binder/rust_binder, PSI, IPv6)
  • Waydroid 通过发行版原生包管理器安装
  • Android 系统镜像通过 waydroid init 下载并挂载
  • waydroid-container.service 开机自启
  • Android 会话可正常启动,桌面 UI 可显示

此时可以:

  • 通过 waydroid app launch 启动系统应用
  • 通过 waydroid app install 安装第三方 APK
  • 在 Android 桌面中以接近原生的性能运行大部分应用

下一步:03 NixOS 深度集成 将详细讲解在 NixOS 上通过声明式配置实现 Waydroid 的完全自动化部署,包括 nftables 网络规则和内核模块管理。


核对依据#

Waydroid 官方安装说明。

Waydroid 官方命令说明。

Waydroid 上游源码。

NixOS 26.05 模块。

参考与延伸

  1. Waydroid 官方安装说明 ↗
  2. Waydroid 官方命令说明 ↗
  3. Waydroid 上游源码 ↗
  4. NixOS 26.05 模块 ↗
  5. NVIDIA 官方 GBM 文档 ↗

根据技术笔记重新整理,示例使用通用名称。

沿专题继续阅读

Waydroid

  1. 01Waydroid 架构:LXC、Binder 与会话桥接
  2. 02Waydroid 安装与基础设置
  3. 03NixOS 中的 Waydroid 集成
  4. 04Waydroid 的 GPU 检测与硬件加速
  5. 05Waydroid 网桥、NAT 与安全边界
  6. 06Waydroid 属性、多窗口与 ARM 转译
  7. 07Waydroid 故障排查与 FAQ
  8. 08Waydroid 使用技巧:窗口、转译和共享目录
CONTINUE READING / 下一篇NixOS 中的 Waydroid 集成

用实际模块源码区分系统声明、Android 镜像和用户运行状态。