Waydroid
Waydroid 是一种基于容器的方法,用于在常规 Linux 系统上启动完整的 Android 系统。
先决条件
CPU 要求
要求取决于 CPU 架构。您可以查看此表格以获取更多信息。
您可以使用 cat /proc/cpuinfo
检查您是否具有所需的 CPU 指令。
GPU 要求
Waydroid 目前在 Intel GPU 上效果最佳。它们应该可以开箱即用。
所有 AMD GPU 均已支持;如果 Waydroid 无法工作,您可能还想尝试构建新的 Waydroid 镜像(适用于 Radeon 680M),或者尝试下面的 NVIDIA 说明。
NVIDIA GPU 目前无法工作,但有 2 种解决方法。
- 如果可能,切换到集成显卡
- 使用软件渲染(参见 #软件渲染)
Wayland 会话管理器
Waydroid 仅在 Wayland 会话管理器中工作,因此请确保您在 Wayland 会话中。
请注意,即使您在 X11 中,许多 Wayland 会话管理器也支持嵌套会话(因此您可以在 X11 会话中运行它),最简单的例子是 cage。
内核模块
您需要运行一个带有 binder 模块的内核。这些模块包含在 linux、linux-lts 和 linux-zen 内核中,但如果您使用不同的 内核,您可能需要通过 DKMS 或重新编译来添加这些模块。
DKMS 模块
安装 binder_linux-dkmsAUR 并加载 内核模块 binder_linux
,模块选项为 devices=binder,hwbinder,vndbinder
(参见 错误报告)。
# modprobe binder-linux devices=binder,hwbinder,vndbinder
或者,您可以在启动时设置加载 binder_linux
,方法是在 /etc/modules-load.d/
和 /etc/modprobe.d/
中创建配置文件(有关更多信息,请参阅 内核模块)。
/etc/modules-load.d/binder_linux.conf
# Load binder_linux at boot binder_linux
/etc/modprobe.d/binder_linux.conf
# Options for binder_linux options binder_linux devices=binder,hwbinder,vndbinder
您还需要使用 内核参数 ibt=off
来解决内核 5.18+ 上的 oops 问题。请参阅 挂载 /dev/binderfs
时出现段错误
构建内核
或者,您可以重新编译 linux 内核 — 或其他内核包(>=5.7)— 并使用必要的选项。另请参阅 Kernel#Compilation。
在构建最小内核时,请记住以下要求
- IPv6 支持。如果您的内核中没有内置 IPv6 网络支持,Waydroid 中将没有 IPv4 连接。
- Netlink 套接字 (
CONFIG_NF_CT_NETLINK=y
)。 - PSI (
CONFIG_PSI=y
)。 - 循环块设备 (
CONFIG_BLK_DEV_LOOP=m
) - 必须在启动 Waydroid 之前加载loop
模块。
在设置编译选项时,您有两个选项可用;binder 和 binderfs。下面提供了两者的说明。
使用 binder
这些模块可以编译到内核中 (y
)、编译为模块 (m
) 或完全不编译 (n
)。此外,并非配置中的所有组合都是可能的,并且某些选项将需要其他选项。
以下配置选项会将 binder 编译为模块,而最后一个选项指定在加载 binder 模块时将在 /dev/
目录中创建三个设备。
CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=m CONFIG_ANDROID_BINDERFS=n CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"
从 AUR 构建内核时,可以使用以下步骤更新配置
- 运行
makepkg --nobuild
,这将下载源文件、验证并提取它们并运行prepare()
函数。 - 编辑
.config
文件(文件名中带有句点),该文件位于内核目录的根目录。 - 在
prepare()
函数的末尾可能有一个命令,该命令使用来自配置的信息重新生成 makefile,可能是make olddefconfig
。将其移动到build()
函数,或自行执行。 - 运行
makepkg --noextract
,这将从makepkg --nobuild
停止的位置继续。
使用 binderfs
已知 binder 内核模块会给一些用户带来问题。为了解决这些问题,创建了 binderfs。在编译内核时,必须在新旧方式之间做出选择。使用以下选项,将使用 binderfs 代替。
内核源代码还附带一个简单的脚本来设置配置选项。它不会像手动编辑配置那样进行依赖项检查。当在 .config
文件所在的同一目录中时,可以执行以下命令
$ scripts/config --enable CONFIG_ANDROID $ scripts/config --enable CONFIG_ANDROID_BINDER_IPC $ scripts/config --enable CONFIG_ANDROID_BINDERFS $ scripts/config --set-str CONFIG_ANDROID_BINDER_DEVICES ""
从 AUR 构建内核时,只需将这些行插入到 PKGBUILD 中的正确位置即可,通常在 prepare()
中。
设置 binder 设备
确保您拥有最新版本的 Waydroid 软件包,Waydroid 将自动处理此问题。
安装
可选地,安装 waydroid-imageAUR 或 waydroid-image-gappsAUR 通过 AUR 提供所需的 Android 镜像。但是,建议让 Waydroid 本身处理镜像下载。
之后初始化 Waydroid,如果最新的 Android 镜像尚不可用,这将自动下载。
# waydroid init
要使用 GApps 支持进行初始化
# waydroid init -s GAPPS
接下来 启动/启用 waydroid-container.service
。
Waydroid 现在应该可以工作了。
用法
确保 waydroid-container.service
已启动,然后运行
$ waydroid session start
Waydroid 会话现在处于活动状态,以下是与它交互的命令示例
启动 GUI
$ waydroid show-full-ui
启动 shell
# waydroid shell
安装应用程序
$ waydroid app install $path_to_apk
获取应用程序列表
$ waydroid app list
运行应用程序
$ waydroid app launch $package_name
网络
网络应该可以开箱即用,如果不是,您可能需要确保在内核中启用了数据包转发,并在运行Waydroid session start之前,允许以下规则通过您的防火墙。
以 ufw 为例
- 需要允许 DNS 流量
# ufw allow 67
# ufw allow 53
- 需要允许数据包转发
# ufw default allow FORWARD
对于 firewalld,您可以使用这些命令
- DNS
# firewall-cmd --zone=trusted --add-port=67/udp
# firewall-cmd --zone=trusted --add-port=53/udp
- 数据包转发
# firewall-cmd --zone=trusted --add-forward
- 将 waydroid 接口添加到 trusted
# firewall-cmd --zone=trusted --add-interface=waydroid0
waydroid0
应该自动位于 firewalld 区域 trusted
中。如果不是这样,请调整上述命令或将接口 waydroid0
移动到 trusted
。您可能还需要# firewall-cmd --runtime-to-permanent使您的更改在重启后持久存在。
技巧与诀窍
启用与桌面窗口管理器集成
waydroid 默认始终以全屏模式运行。
如果您希望 waydroid 与您的桌面环境窗口管理器集成
使用以下命令启动 waydroid 会话
$ waydroid session start
设置所需的属性
$ waydroid prop set persist.waydroid.multi_windows true
现在应用程序应该在其自己的桌面窗口中启动。
更多信息请参见 官方文档
软件渲染
确保您已运行
# waydroid init
(有关更多信息,请参阅 #安装 部分)
然后,添加以下内容
/var/lib/waydroid/waydroid_base.prop
ro.hardware.gralloc=default ro.hardware.egl=swiftshader
最后,重启 waydroid-container.service
。
设置视口尺寸
要设置 waydroid 窗口的尺寸,请使用以下命令,并根据您的喜好调整尺寸
$ waydroid prop set persist.waydroid.width 576 $ waydroid prop set persist.waydroid.height 1024
然后 重启 waydroid-container.service
。
故障排除
如果您遇到问题,请查看官方问题跟踪器:Waydroid issue tracker。
通用技巧
Waydroid 正在快速开发中,因此如果您遇到问题,以下是首先要执行的步骤列表
- 确保您的 Waydroid 软件包是最新的。
- 通过运行以下命令确保您拥有最新的 Waydroid 镜像
# waydroid upgrade
- 重置 Waydroid:停止
waydroid-container.service
,运行# waydroid init -f
并启动服务。 - 您可能还需要进行少量清理,运行
# rm -rf /var/lib/waydroid /home/.waydroid
$ rm -rf ~/waydroid ~/.share/waydroid ~/.local/share/applications/*aydroid* ~/.local/share/waydroid
- 提示: 如果您在 2021-09 之后安装了它,则无需删除
/home/.waydroid/
。
ARM 应用不兼容
使用 casualsnek 的 脚本 安装翻译层。
由于翻译层中的优化,建议在 AMD CPU 上使用 libndk,在 Intel CPU 上使用 libhoudini。但是,某些应用在一个翻译层上可以工作,而在另一个翻译层上则不能。因此,如果游戏无法工作或性能不佳,您可能需要尝试两者。
安装 libndk arm 翻译
# python3 main.py install libndk
安装 libhoudini arm 翻译
# python3 main.py install libhoudini
旋转的应用无法使用
参见 Issue 70。
单击 F11 将当前应用切换到窗口模式。
无法启动剪贴板管理器服务
安装 python-pyclipAUR 及其图形会话的依赖项 (xclip 用于 X11 或 wl-clipboard 用于 Wayland)。
有时物理键盘无法工作
按下左侧的 Alt
键。
dnsmasq: failed to open pidfile /run/waydroid-lxc/dnsmasq.pid: Permission denied
很可能未设置 AppArmor 规则。添加以下规则
/etc/apparmor.d/usr.sbin.dnsmasq
@{run}/waydroid-lxc/ r, @{run}/waydroid-lxc/* rw,
Waydroid shell 内的命令输出无法访问或未找到
在基于 Arch 的发行版中,存在一个 “bug”,在使用 lxc-attach 时可能会出现,这可能会导致 waydroid shell
内的命令(如 adbd
或 settings
)出现此问题。
一个可能的解决方法是用以下命令替换 waydroid shell
命令
# lxc-attach -P /var/lib/waydroid/lxc/ -n waydroid --clear-env
WARNING: Service manager /dev/binder has died
参见 Issue 136。
您应该启用 PSI。
将 psi=1
添加到 内核命令行。
请注意,Liquorix 内核 永远无法与 Waydroid 一起工作,因为它使用某些与 PSI 不兼容的调度程序。
多 GPU 系统上的图形损坏
目前,Waydroid 需要在主机合成器运行的同一 GPU 上运行。解决此问题的两种方法是编辑 /var/lib/waydroid/lxc/waydroid/config_nodes
以使其成为正确的 GPU,或更改合成器运行的 GPU。
没有互联网连接
根据 waydroid/issue/509,Waydroid 已知与 docker 存在 nftables 冲突。
要解决此问题,请关闭 LXC_USE_NFT
作为一种解决方法
/usr/lib/waydroid/data/scripts/waydroid-net.sh
LXC_USE_NFT="false"
或运行以下命令
# systemctl stop docker # systemctl restart iptables # ip link delete docker0 # systemctl restart waydroid-container
This device isn't Play Protect certified
参见: https://docs.waydro.id/faq/google-play-certification
如果您收到此错误,您需要进入 waydroid shell 并检索 android id
# waydroid shell # ANDROID_RUNTIME_ROOT=/apex/com.android.runtime ANDROID_DATA=/data ANDROID_TZDATA_ROOT=/apex/com.android.tzdata ANDROID_I18N_ROOT=/apex/com.android.i18n sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "select * from main where name = \"android_id\";"
之后,将 id 输入到此网站: https://www.google.com/android/uncertified
等待几分钟并重启 waydroid。
Waydroid 一段时间后挂起
这可能是由于音频服务器崩溃所致,请参阅 Issue 576 和 Issue 829 了解详细信息。
一种解决方法是运行
# sysctl -w kernel.pid_max=65535
您可以通过在 /etc/sysctl.d/
中创建一个 .conf
文件并在其中添加 kernel.pid_max=65535
使其永久生效。
/etc/sysctl.d/99-sysctl.conf
kernel.pid_max=65535