huchuan2025/30-Resource/在Archlinux上使用waydroid运行安卓ap...

431 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 零、前言说明
本教程使用[systemd-networkd](https://zhida.zhihu.com/search?content_id=228426250&content_type=Article&match_order=1&q=systemd-networkd&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NDEyNzgxNzEsInEiOiJzeXN0ZW1kLW5ldHdvcmtkIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjI4NDI2MjUwLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.MuX51TS-DGdgd_khAzFgU2o4epNjqnd-nm-gshNOpy4&zhida_source=entity)、[systemd-resolved](https://zhida.zhihu.com/search?content_id=228426250&content_type=Article&match_order=1&q=systemd-resolved&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NDEyNzgxNzEsInEiOiJzeXN0ZW1kLXJlc29sdmVkIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjI4NDI2MjUwLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.xLpnWJkVi1abK39e8We03bBLFznCVkP2y06Fzw8mC6A&zhida_source=entity)及nftables配置waydroid的网络与官方基于iproute2、dnsmasq及iptables的方法不同。原因是我的[qemu-KVM](https://zhida.zhihu.com/search?content_id=228426250&content_type=Article&match_order=1&q=qemu-KVM&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NDEyNzgxNzEsInEiOiJxZW11LUtWTSIsInpoaWRhX3NvdXJjZSI6ImVudGl0eSIsImNvbnRlbnRfaWQiOjIyODQyNjI1MCwiY29udGVudF90eXBlIjoiQXJ0aWNsZSIsIm1hdGNoX29yZGVyIjoxLCJ6ZF90b2tlbiI6bnVsbH0.yNwEyB-UtEuIhhbjubReR7v13J0IbCztvViW1Q-BXF0&zhida_source=entity)虚拟机网络也是基于systemd、nftables配置的这种方法更为现代化且比iproute2、dnsmasq及iptables繁琐的规则简单多了。
waydroid是基于lxc的容器方案能在X86_64位CPU上运行原生安卓系统(LineageOS X86_64系统)与宿主机器共享同一个linux内核(包括你自己编译优化的内核)能直接调用宿主机显卡硬件是目前所有安卓兼容方案中性能最高的。但是需要添加ARM转译层(libhoudini或libndk)的支持才能运行绝大多数手机app这点教程里会教你。
waydroid的图形实现是[wayland](https://zhida.zhihu.com/search?content_id=228426250&content_type=Article&match_order=1&q=wayland&zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NDEyNzgxNzEsInEiOiJ3YXlsYW5kIiwiemhpZGFfc291cmNlIjoiZW50aXR5IiwiY29udGVudF9pZCI6MjI4NDI2MjUwLCJjb250ZW50X3R5cGUiOiJBcnRpY2xlIiwibWF0Y2hfb3JkZXIiOjEsInpkX3Rva2VuIjpudWxsfQ.fC0vV7nX5opGbf1h4Et5F288XD8TE3HA6XGir_SaT2o&zhida_source=entity)所以你的linux桌面必须是以wayland环境启动(KDE、Gnome、sway、Hyprland、Weston等)。不要再想着你的X11了这种老旧的协议应该早点淘汰。
教程里有一些重复的步骤,尤其是"修改waydroid的网络配置",不要觉得麻烦就跳过,这些步骤都是设计好的,没有多余的步骤。跳过的话你执行"waydroid session start"命令是不会成功的。
## 一、首先准备编译内核
**写在前头**不会配置编译内核的朋友请换用Archlinux的linux-zen内核然后在你们grub内核引导配置的末尾加上一个"psi=1"就ok了。
```
选中所有cgroup和namespace的子选项
CONFIG_CGROUP_FAVOR_DYNMODS=n
CONFIG_PSI=y
CONFIG_PSI_DEFAULT_DISABLED=n
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
CONFIG_VETH=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_BINDERFS=y
CONFIG_ANDROID_BINDER_DEVICES=""
CONFIG_ANDROID_BINDER_IPC_SELFTEST=n
CONFIG_EXT4_FS=y
CONFIG_EXT4_USE_FOR_EXT2=y
#"n"表示取消选择
```
![](https://picx.zhimg.com/v2-1e5a5b2ea2d62bcd75342c93468baecf_1440w.jpg)
![](https://picx.zhimg.com/v2-8fba7c72cec95e77c108c1b134a255e3_1440w.jpg)
![](https://pica.zhimg.com/v2-00447a18e2c1d191911d69f5983fd474_1440w.jpg)
![](https://pic3.zhimg.com/v2-185ab9e7b2157479e4b96f57c984bce6_1440w.jpg)
![](https://pic3.zhimg.com/v2-fb097c6966afd4f37a94c9aaac32e280_1440w.jpg)
重新编译并安装内核(参见我的内核编译教程)
## 二、下载waydroid和image
```
在pacman里添加archlinuxcn源
sudo pacman -Syu
sudo pacman -S waydroid waydroid-image
paru -S python-pyclip
```
```
sudo waydroid init -f -i /usr/share/waydroid-extra/images
sudo systemctl enable waydroid-container.service
sudo systemctl start waydroid-container.service
```
这里先不启动waydroid我们先配置网络
## 四、配置网络(使用systemd-networkd和nftables)
更改以下脚本删除关于iproute2和dnsmasq的设置
```
sudo nano /usr/lib/waydroid/data/scripts/waydroid-net.sh :
#!/bin/bash
echo "mama"
#每次waydroid更新后均需要修改此脚本
```
修改waydroid的网络配置
```
sudo nano /var/lib/waydroid/lxc/waydroid/config :
找到网络配置的那一段,改为以下
lxc.net.0.type = veth
lxc.net.0.flags = up
#lxc.net.0.link = waydroid0
lxc.net.0.name = eth0
lxc.net.0.hwaddr = 00:16:3e:f9:d3:03
lxc.net.0.mtu = 1500
lxc.net.0.veth.pair = waydroid0
#每次waydroid更新后均需要修改此配置文件
```
修改systemd-networkd的网络配置
```
sudo nano /etc/systemd/network/waydroid0.network :
[Match]
Name=waydroid0
[Network]
Address=192.168.24.1/24
DHCPServer=true
IPForward=yes
```
修改nftables的防火墙配置
```
sudo nano /etc/nftables.conf :
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
iifname "lo" accept
iifname "waydroid0" accept
ct state established,related accept
ct state invalid drop
}
chain output {
type filter hook output priority filter; policy accept;
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iifname "waydroid0" oifname "wlan0" accept
iifname "wlan0" oifname "waydroid0" accept
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
iifname "waydroid0" oifname "wlan0" masquerade
}
}
#其中"wlan0"更改为你自己用于连接外部网络上网的设备,用"ip a"命令查看
```
启用ip转发
```
sudo nano /etc/sysctl.d/90-override.conf :
net.ipv4.ip_forward = 1
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1
net.ipv6.conf.all.forwarding = 1
```
停用dnamasq、dhcpd、networkmanager网络服务及iptables防火墙他们会和systemd-networkd、systemd-resolved和nftables冲突
```
sudo systemctl disable dnsmasq.service
sudo systemctl disable dhcpd.service
sudo systemctl disable NetworkManager.service
sudo systemctl disable iptables.service
```
启用systemd-networkd、systemd-resolved和nftables
```
sudo rm /etc/resolv.conf
sudo ln -rsf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
sudo systemctl enable systemd-networkd.service
sudo systemctl enable systemd-resolved.service
sudo systemctl enable nftables.service
```
好了,重启电脑
## 五、为waydroid安装arm兼容层
终端里执行
完成后退出执行("ctrl+c"终止运行)
安装相关依赖及脚本
```
sudo pacman -S lzip sqlite
paru -S waydroid-script-git
```
AMD的cpu安装libndk
Intel的cpu安装libhoudini
修改waydroid的网络配置
```
sudo nano /var/lib/waydroid/lxc/waydroid/config :
找到网络配置段,改为以下
lxc.net.0.type = veth
lxc.net.0.flags = up
#lxc.net.0.link = waydroid0
lxc.net.0.name = eth0
lxc.net.0.hwaddr = 00:16:3e:f9:d3:03
lxc.net.0.mtu = 1500
lxc.net.0.veth.pair = waydroid0
```
## 六、使用waydroid
终端里执行,不终止退出
为waydroid配置网关
```
echo "ip route add default via 192.168.24.1" | sudo waydroid shell
#这一步很重要,不配置网关无法上网。此命令必须随每一次"waydroid session start"启动而执行一次,否则失效
```
接下来即可进入waydroid图形界面开始上网
## 七、小技巧
列出waydroid系统里安装的包及包名
安装安卓应用
```
waydroid app install /path/to/apk
```
不启动安卓界面只启动一个app
```
waydroid app launch $package-name #Can be retrieved with `waydroid app list`
```
有的app不识别鼠标点击事件
```
waydroid prop set persist.waydroid.fake_touch $package-name
#此命令必须随每一次"waydroid session start"启动而执行一次,否则失效
```
有的app即使联网了也不能上网浏览器能上网但不能下载东西
```
waydroid prop set persist.waydroid.fake_wifi $package-name
#此命令必须随每一次"waydroid session start"启动而执行一次,否则失效
```
## 八、Trouble Shooting
1. 一些ARM应用无法正常启动
```
事关libndk和libhoudini本身的兼容性无解只能等待google和intel更新
```
2. 一些app和游戏无法识别键盘和鼠标只识别触摸屏事件极大阻碍waydroid实际使用体验
```
1、使用qtscrcpy但是键盘鼠标映射配置复杂通过adb投屏的画质差、延迟高
2、下载安卓键鼠映射app比如panda mouse pro、八爪鱼相关教程去B站上搜反正我是没成功过
3、此类问题最有希望的是waydroid官方上游加入类似windows平台上mumu、雷电模拟器的键鼠映射支持否则基本无解
```
目前我只找到了键盘映射触屏事件的app即Key Mapper+Shizuku。鼠标映射触屏实在是没办法。
![](https://pic3.zhimg.com/v2-b99e6110c644b87a70f6999c9032ecc4_1440w.jpg)
![](https://pic2.zhimg.com/v2-03b48fb71ac42d1ccc19fdd9132fa261_1440w.jpg)
![](https://pic2.zhimg.com/v2-d8286994a0ba1c7529e5f5bf64ebd37f_1440w.jpg)
**不玩游戏时记得把上述键盘映射关了,免得影响日常输入法体验。**
关于在映射触屏tap事件时如何获取屏幕触击坐标
首先开启开发者模式
```
设置-->关于手机-->版本号,连续点击"版本号"7次以上
```
然后
```
系统-->高级-->开发者选项-->指针位置,开启"指针位置"
```
此时长按鼠标左键即可在屏幕上方显示当前触击点的x,y坐标。
3. 一些app启动后默认竖屏导致屏幕翻转鼠标操控困难
```
安装一款名叫Rotation的app,不用破解版也行。上网随便一搜就能找到。
```
![](https://pic4.zhimg.com/v2-cd4b4e3b17e2cd365e4f20456d50573f_1440w.jpg)
右下角Rotation
![](https://pic2.zhimg.com/v2-3e4554ea82d2ee700163a3dea55554c5_1440w.jpg)
如红色选中的设置为强制横屏
![](https://pic4.zhimg.com/v2-deb3b4445367b0a147aff1f68570a305_1440w.jpg)
设置为开机启动
**注意**强制横屏后原本你在Key Mapper里配置的竖屏app的触屏事件坐标会对应不上需要重新配置改为横屏后的触屏坐标。
## 九、挂载宿主机目录到waydroid内部目录里
比如
```
sudo mount --bind /home/zouzi/ ~/.local/share/waydroid/data/media/0/Download/
```
之后你就可以在waydroid系统里的Download目录里看见你宿主机上的内容了
```
每一次"waydroid session start"启动后,需要先执行
sudo umount ~/.local/share/waydroid/data/media/0/Download/
再执行
sudo mount --bind /home/zouzi/ ~/.local/share/waydroid/data/media/0/Download/
否则挂载失效
```
若重复两次及以上挂载waydroid系统里不会看到宿主机上的内容。这时候需要
```
多次重复执行
sudo umount ~/.local/share/waydroid/data/media/0/Download/
```
直到出现提示
```
umount: /home/zouzi/.local/share/waydroid/data/media/0/Download/: not mounted.
```
再次执行一次
```
sudo mount --bind /home/zouzi/ ~/.local/share/waydroid/data/media/0/Download/
```
就可以了
## 十、删除所有waydroid配置重新安装
有的时候遇到难以修改的问题可以删除所有的waydroid文件及配置重新安装
```
sudo systemctl stop waydroid-container.service
sudo rm -rf /var/lib/waydroid/ /home/.waydroid/ ~/waydroid/ ~/.share/waydroid/ ~/.local/share/applications/*aydroid*/ ~/.local/share/waydroid/
sudo pacman -S waydroid-image #重新安装waydroid镜像这一步必不可少
sudo waydroid init -f -i /usr/share/waydroid-extra/images
sudo systemctl start waydroid-container.service
```
修改waydroid的网络配置
```
sudo nano /var/lib/waydroid/lxc/waydroid/config :
找到网络配置段,改为以下
lxc.net.0.type = veth
lxc.net.0.flags = up
#lxc.net.0.link = waydroid0
lxc.net.0.name = eth0
lxc.net.0.hwaddr = 00:16:3e:f9:d3:03
lxc.net.0.mtu = 1500
lxc.net.0.veth.pair = waydroid0
```
执行
完成后退出
AMD的cpu安装libndk
Intel的cpu安装libhoudini
修改waydroid的网络配置
```
sudo nano /var/lib/waydroid/lxc/waydroid/config :
找到网络配置段,改为以下
lxc.net.0.type = veth
lxc.net.0.flags = up
#lxc.net.0.link = waydroid0
lxc.net.0.name = eth0
lxc.net.0.hwaddr = 00:16:3e:f9:d3:03
lxc.net.0.mtu = 1500
lxc.net.0.veth.pair = waydroid0
```
启动waydroid
```
waydroid session start
echo "ip route add default via 192.168.24.1" | sudo waydroid shell
waydroid show-full-ui
```
## 十一、如何执行root操作
waydroid里的LineageOS X86_64安卓系统并没有被预先root。
一些app可能需要通过开启安卓系统ADB调试的方式来获取root权限。如Shizuku需要连接USB ADB调试或Wifi ADB调试后执行
```
adb shell sh /storage/emulated/0/Android/data/moe.shizuku.privileged.api/start.sh
```
才能激活运行。
但是waydroid容器不用那么复杂只需要在宿主机上执行
即可以最高root权限进入waydroid系统内执行命令
```
sh /storage/emulated/0/Android/data/moe.shizuku.privileged.api/start.sh
#此命令必须随每一次"waydroid session start"启动而执行一次,否则失效
```
不用开启USB ADB调试或Wifi ADB调试即可成功激活Shizuku。
激活命令可以改为
```
echo "sh /storage/emulated/0/Android/data/moe.shizuku.privileged.api/start.sh" | sudo waydroid shell
#此命令必须随每一次"waydroid session start"启动而执行一次,否则失效
```
在宿主机终端里执行。
## 十二、最终实现效果
目前我通过自己编译配置内核已经实现了qemu-KVM虚拟机运行win10系统办公微信写论文、waydroid容器运行安卓游戏、steam proton玩游戏、yuzu模拟器玩塞尔达旷野之息和王国之泪、pcsx2模拟器玩老PS2经典游戏、webd服务器自建网盘、mpv+SVP+Anime4k高清60帧看番剧。我的linux桌面系统正在被我调教成一个兼具办公和娱乐的高性能六边形战士感觉十分有趣。