让安卓应用像原生窗口一样开在 Linux 桌面上:Waydroid 多窗口实操
记录把 Waydroid 从「一整个安卓桌面」调成「每个应用一个独立窗口」的完整流程:镜像选择、window HAL 校验、安装 APK 的正确姿势,以及为什么很多镜像根本开不出多窗口。
Waydroid 默认给你的是「一整个安卓桌面」:一个窗口,里面是完整的 Android,应用都在里面跑。这和「像原生应用一样,在旁边开一个窗口」的体验差得很远。
好消息是 Waydroid 确实有多窗口模式(multi-window),开启后每个 Android 应用都是合成器里的一个独立 toplevel,可以和原生窗口切列、并排、浮动。坏消息是它能不能用,几乎完全取决于你装的是哪套镜像——这一点在文档里几乎没写。
下面是我在这台机器(Arch + niri + Waydroid 1.6.3)上跑通的最终流程。

waydroid app launch cn.com.langeasy.LangEasyLexis 之后,桌面多出一个窗口:
app_id: waydroid.cn.com.langeasy.LangEasyLexis
title : 不背单词
size : 1707x1033再启动「设置」,又多一个 waydroid.com.android.settings 窗口,两个窗口同时存在。窗口没有服务端装饰(合成器本来也不画边框),其余行为与原生窗口一致。
多窗口不是纯宿主侧的开关。Android 框架要把每个任务窗口导出成 Wayland surface,靠的是 vendor 侧的 HIDL HAL:[email protected]::IWaydroidWindow。
先启动会话,然后进容器验证:
waydroid session start &
sudo waydroid shell -- lshal | grep waydroid能用的镜像会看到类似这样的行(DM, Y 表示清单已声明、框架兼容):
DM Y [email protected]::IWaydroidWindow/default
DM Y [email protected]::IWaydroidWindow/default如果这里只看到 vendor.waydroid.task,或者什么都没有,那这套镜像就永远开不出多窗口。 我在一套第三方 Android 17 镜像上就是这种情况,logcat 里明确写着:
W WayDroidService: Waydroid window HAL unavailable
I hwservicemanager: Cannot find entry [email protected]::IWaydroidWindow/default那套镜像里只有客户端 stub([email protected]),没有服务端实现;而且它的 system.img 是 EROFS 只读,多窗口还依赖把 pc.xml(android.hardware.type.pc)bind 到 /system/etc/permissions/,目标文件不存在又写不进去,规则直接失效。补 VINTF 声明也没用——没有服务进程,声明了照样找不到。
结论:换镜像,不要试图修补。
paru -S waydroid --needed
sudo waydroid init # 官方 LineageOS 20 (Android 13) VANILLA + MAINLINE vendor确认 images_path 指向这套官方镜像(/var/lib/waydroid/waydroid.cfg 里的 images_path)。第三方镜像如果是放在 /etc/waydroid-extra/images/ 那种,切回来改这一行即可。
waydroid session start &
waydroid prop set persist.waydroid.multi_windows trueprop set 只改运行期;要开机就生效,直接写进配置文件:
echo 'persist.waydroid.multi_windows=true' | sudo tee -a /var/lib/waydroid/waydroid.prop然后重启会话让它进容器:
waydroid session stop
waydroid session start &
waydroid status # Session: RUNNING / Container: RUNNINGwaydroid app install ~/Downloads/app.apk这条命令走的是 Waydroid 自己的 IPlatform.installApp,某些镜像上会因为缺 persistent_data_block 服务在 PackageInstallerSession.markAsSealed 抛异常而失败。稳妥的做法是绕开它,直接进容器用 pm:
mkdir -p ~/.local/share/waydroid/data/waydroid_tmp
cp ~/Downloads/app.apk ~/.local/share/waydroid/data/waydroid_tmp/
sudo waydroid shell -- pm install -r -g /data/waydroid_tmp/app.apk # Success
sudo waydroid shell -- pm list packages -3 # 确认包名waydroid app launch cn.com.langeasy.LangEasyLexis窗口就该出现了。多个应用分别 app launch 就是多个窗口。
坑一:冷启动会弹出整个安卓桌面。 waydroid app launch 在会话未运行时,会用 background=False 起会话(session_manager.py → waydroid.background_start=false),Android 于是直接展示整套 UI。想只出应用窗口,必须先 waydroid session start(background=True),再 launch。
坑二:NoDisplay 与自动生成的桌面条目。 Waydroid 自带的 user_manager 服务会为每个 Android 应用生成 ~/.local/share/applications/waydroid.<包名>.desktop,图标导出到 ~/.local/share/waydroid/data/icons/。系统应用会自动带 NoDisplay=true,所以启动器里通常只多出你自己装的那几个。想自定义名称/图标,别去改它生成的那份(每次用户解锁都会被重写),另建一份、给它加 NoDisplay=true 更稳。
坑三:窗口尺寸交给合成器。 Waydroid 不负责窗口装饰和尺寸。用 niri 的话加一条规则就够了:
window-rule {
match app-id=r#"^waydroid\."#
default-column-width { proportion 0.5; }
}官方 Android 13 VANILLA 镜像不带 Google 服务,这是多窗口能用的代价。需要 GApps 的话得自己给这套镜像打补丁(如 waydroid_script),而不是换回缺 window HAL 的新版第三方镜像。
另外,多窗口模式意味着你不再有一个「安卓桌面」可用:所有操作都得从应用窗口发起。如果偶尔确实需要整套 UI,waydroid show-full-ui 还能叫出来。
一句话总结:多窗口是镜像能力,不是开关能力。先 lshal | grep waydroid.window 确认服务在跑,再谈其他。
除另有说明,本文内容采用 CC BY-NC-SA 4.0 协议许可。转载或改编请署名、非商业使用,并以相同方式共享。