01 aosp 环境准备
repo工具,需要使用国内镜像,不要采用安装的方式,安装的repo工具,默认会找官网地址
aosp android 源码代码线、tag信息: https://android.googlesource.com/platform/manifest/+refs
aosp android 源码下载 官网说明: https://source.android.com/docs/setup/download?hl=zh-cn
win10 hyperV ubuntu2024.04desktop 虚拟机
02. 初始化仓库(指定最新稳定 Tag)
# 手动安装repo
mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH
# 可以在 ~/.bashrc 中指定 repo 工具去清华镜像拉取清单(manifest)和代码
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
export REPO_REMOTE='tuna'
# sudo apt update -y
# sudo apt upgrade -y
# repo init -u https://android.googlesource.com/platform/manifest -b android-16.0.0_r4
# 使用清华镜像初始化,指定精确 Tag
# --depth=1 仅拉取当前分支最新提交,可节省约 40% 初始下载量与时间。若后续需完整 Git 历史,可省略此参数。
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-16.0.0_r4 --depth=1
## 中科大 USTC https://mirrors.ustc.edu.cn/aosp/platform/manifest 同步频率高,节点分布广
## 阿里云 Codeup https://code.aliyun.com/AOSP-Archive/platform/manifest.git 适合企业内网,需注册账号
## 腾讯云 COS https://mirrors.cloud.tencent.com/aosp/platform/manifest 华南地区延迟低
03. 高效同步
#repo sync -c -j$(nproc) --optimized-fetch --prune --no-tags
repo sync -c -j$(nproc) --optimized-fetch --prune
# 📌 参数说明:
# -c:仅同步当前分支,跳过无关历史
# -j$(nproc):按 CPU 核心数并行下载(建议 8~16 线程,避免内存溢出)
# --optimized-fetch:复用已有对象,加速增量同步
# --prune:自动清理远程已删除的引用
04. 查看信息
source build/envsetup.sh
list_products | grep car
# aosp_cheetah_car
# aosp_husky_car
# aosp_panther_car
# aosp_tangorpro_car
# gsi_car_arm64
# gsi_car_x86_64
# sdk_car_arm64
# sdk_car_cw_x86_64
# sdk_car_dewd_x86_64
# sdk_car_md_arm64
# sdk_car_md_x86_64
# sdk_car_x86_64
list_variants
# user
# userdebug
# eng
05. 编译多窗口 aaos 环境配置
source build/envsetup.sh && export OUT_DIR=out_sdk_car_md_x86_64 && export TARGET_PRODUCT=sdk_car_md_x86_64 && lunch sdk_car_md_x86_64 aosp_current userdebug
09:22:03 Build sandboxing disabled due to nsjail error.
device/generic/car/sdk_car_md_x86_64.mk:26: warning: sdk_car_md_x86_64 is for development purposes only.
device/generic/car/sdk_car_md_x86_64.mk:26: warning: sdk_car_md_x86_64 is for development purposes only.
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=16
TARGET_PRODUCT=sdk_car_md_x86_64
TARGET_BUILD_VARIANT=userdebug
TARGET_ARCH=x86_64
TARGET_ARCH_VARIANT=x86_64
TARGET_2ND_ARCH_VARIANT=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-6.17.0-20-generic-x86_64-Ubuntu-24.04.4-LTS
HOST_CROSS_OS=windows
BUILD_ID=BP4A.251205.006
OUT_DIR=out_sdk_car_md_x86_64
SOONG_ONLY=false
============================================
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Wondering whether to use user, userdebug or eng?
user The builds that ship to users. Reduced debugability.
userdebug High fidelity to user builds but with some debugging options
enabled. Best suited for performance testing or day-to-day use
with debugging enabled.
eng More debugging options enabled and faster build times, but
runtime performance tradeoffs. Best suited for day-to-day
local development when not doing performance testing.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
06. 编译
# 物理机器是 intel 的x86架构,所以编译了x86_64架构的版本
# 单模块编译命令: m -j$(nproc) webview
# 需要有android编译时的环境变量,如果是新窗口,需运行如下命令后,再运行编译命令 m -j$(nproc);
# source build/envsetup.sh && export OUT_DIR=out_sdk_car_md_x86_64 && export TARGET_PRODUCT=sdk_car_md_x86_64 && lunch sdk_car_md_x86_64 aosp_current userdebug
m -j$(nproc)
# 出现如下错误
internal error: Device makefile has PRODUCT_SYSTEM_PROPERTIES or PRODUCT_SYSTEM_
DEFAULT_PROPERTIES that add properties to the 'system' partition, which is again
st packages/services/Car/car_product/build/car_generic_system.mk's artifact path
requirement.
Please use PRODUCT_PRODUCT_PROPERTIES or PRODUCT_SYSTEM_EXT_PROPERTIES to add th
em to a different partition instead.
Offending entries:
com.android.car.internal.debug.num_auto_populated_users=1
cppd.connectvhal.Timeoutmillis=60000
persist.sys.max_profiles=5
ro.vendor.simulateMultiZoneAudio=true
09:26:36 soong bootstrap failed with: exit status 1
# AOSP 16 的车机构建脚本 (car_generic_system.mk) 强制禁止向 system 分区写入属性。设备配置文件中使用了 PRODUCT_SYSTEM_PROPERTIES 或 PRODUCT_SYSTEM_DEFAULT_PROPERTIES 添加了 cppd.connectvhal.Timeoutmillis=60000,触发了分区隔离策略校验。
# 需要把 PRODUCT_SYSTEM_PROPERTIES ==> PRODUCT_PRODUCT_PROPERTIES;PRODUCT_SYSTEM_DEFAULT_PROPERTIES ==> PRODUCT_PRODUCT_PROPERTIES
# 需要对如下位置进行修改
# device/generic/car/emulator/car_emulator_vendor.mk:62:# PRODUCT_SYSTEM_PROPERTIES += cppd.connectvhal.Timeoutmillis=60000 ==>PRODUCT_PRODUCT_PROPERTIES
# device/generic/car/common/car.mk:26:# PRODUCT_SYSTEM_PROPERTIES += cppd.connectvhal.Timeoutmillis=60000 ==>PRODUCT_PRODUCT_PROPERTIES
# device/generic/car/common/car_md.mk:43:# PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \ ==>PRODUCT_PRODUCT_PROPERTIES
# device/google/cuttlefish/shared/auto/device_vendor.mk:94:# PRODUCT_SYSTEM_PROPERTIES += cppd.connectvhal.Timeoutmillis=60000 ==>PRODUCT_PRODUCT_PROPERTIES
# device/google/cuttlefish/vsoc_x86_64_only/auto_md/aosp_cf.mk:38:# PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \ ==>PRODUCT_PRODUCT_PROPERTIES
# :: 编译后生成产物目录:
# zfjvm01@zfjvm0-vm:~/workspace/git/aosp16$ ls -l out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/*.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 16777216 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/cache.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 13 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/dtb.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 18874368 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/encryptionkey.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 425734144 4月 15 15:56 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/product.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 428867584 4月 15 15:56 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/product-qemu.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 1794131 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/ramdisk.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 1902444 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/ramdisk-qemu.img
# -rw------- 1 zfjvm01 zfjvm01 4644 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/super_empty.img
# -rw-r--r-- 1 zfjvm01 zfjvm01 5856296960 4月 15 15:56 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/super.img
# -rw-r--r-- 1 zfjvm01 zfjvm01 8077312 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/system_dlkm.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 10485760 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/system_dlkm-qemu.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 184918016 4月 15 15:56 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/system_ext.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 187695104 4月 15 15:56 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/system_ext-qemu.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 1272848384 4月 15 15:56 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/system.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 5859442688 4月 15 15:56 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/system-qemu.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 576716800 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/userdata.img
# -rw------- 1 zfjvm01 zfjvm01 6356992 4月 15 14:47 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/userdata-qemu.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 65536 4月 15 15:56 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/vbmeta.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 100663296 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/vendor_boot-debug.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 100663296 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/vendor_boot.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 421888 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/vendor_boot-test-harness.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 119431168 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/vendor.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 121634816 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/vendor-qemu.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 412954 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/vendor_ramdisk-debug.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 108313 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/vendor_ramdisk.img
# -rw-rw-r-- 1 zfjvm01 zfjvm01 413339 4月 15 14:45 out_sdk_car_md_x86_64/target/product/emulator_car64_x86_64/vendor_ramdisk-test-harness.img
07 运行模拟器
07.01 构建在 虚拟机ubuntu2024.04desktop中运行模拟器的环境
07.01.01 在 Guest 机器上面(B:虚拟机ubuntu2024.04desktop)上启用 kvm,支持qemu模拟器
# 1. 环境变量初始化正常后,直接启动,它会自动识别正确的 img 文件,
emulator -no-snapshot -gpu swiftshader_indirect -memory 4096 -partition-size 4096
# 2. 如果出现kvm错误提示,大概率是没有启用kvm支持
egrep -c '(vmx|svm)' /proc/cpuinfo
0 # 结果 0 = 无法在 Ubuntu 里高效运行其他虚拟机/模拟器。请去虚拟机软件设置里开启 "虚拟化引擎" 或 "嵌套虚拟化" 功能。
kvm-ok
#如果显示:找不到命令 "kvm-ok",但可以通过以下软件包安装它:
sudo apt install cpu-checker
kvm-ok
INFO: Your CPU does not support KVM extensions
INFO: For more detailed results, you should run this as root
3. 安装 KVM 相关包
sudo apt update
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager
4. 加载 KVM 内核模块
sudo modprobe kvm
sudo modprobe kvm_intel # 如果是 Intel CPU
# 或者
sudo modprobe kvm_amd # 如果是 AMD CPU
zfjvm01@zfjvm0-vm:~/workspace/git$ sudo modprobe kvm
sudo modprobe kvm_intel # 如果是 Intel CPU
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported
zfjvm01@zfjvm0-vm:~/workspace/git$ sudo modprobe kvm
zfjvm01@zfjvm0-vm:~/workspace/git$ sudo modprobe kvm_intel
modprobe: ERROR: could not insert 'kvm_intel': Operation not supported
zfjvm01@zfjvm0-vm:~/workspace/git$ sudo modprobe kvm_amd
modprobe: ERROR: could not insert 'kvm_amd': Operation not supported
5. 关键步骤:将当前用户加入 kvm 组
默认情况下,只有 root 能访问 /dev/kvm。你需要将你的用户 zfjvm01 加入 kvm 和 libvirt 组:
sudo adduser $USER kvm
sudo adduser $USER libvirt
07.01.02 在Host(A:win10)机器上面启用支持嵌套虚拟化
::重要:执行完上述命令后,必须注销并重新登录 Ubuntu,或者重启系统,权限才会生效!
::⚠️ 【重要】如果你是在 VMWare/VirtualBox 中运行 Ubuntu
::因为你主机名是 zfjvm0-vm,我推测你是在虚拟机里跑 Ubuntu。在这种情况下,仅仅在 Ubuntu 里安装 KVM 是不够的,你必须在宿主机(物理机)上开启嵌套虚拟化(Nested Virtualization)。
:: 管理原权限启动 PowerShell
:: 查看 虚拟化支持情况 Get-VM
PS C:\Windows\system32> get-vm
Name State CPUUsage(%) MemoryAssigned(M) Uptime Status Version
---- ----- ----------- ----------------- ------ ------ -------
hu2404tls01 Off 0 0 00:00:00 正常运行 9.0
u2604tls01 Off 0 0 00:00:00 正常运行 9.0
:: 设置支持嵌套虚拟化
Set-VMProcessor -VMName "hu2404tls01" -ExposeVirtualizationExtensions $true
:: 查看对嵌套虚拟化的支持(ExposeVirtualizationExtensions==True表示已支持)
Get-VMProcessor -VMName "hu2404tls01" | Select-Object ExposeVirtualizationExtensions
PS C:\Windows\system32> Set-VMProcessor -VMName "hu2404tls01" -ExposeVirtualizationExtensions $true
PS C:\Windows\system32>
PS C:\Windows\system32> Get-VMProcessor -VMName "hu2404tls01" | Select-Object ExposeVirtualizationExtensions
ExposeVirtualizationExtensions
------------------------------
True
07.01.03 再次检查Guest(B:ubuntu2024.04desktop)里面对kvm的支持
执行好1,2步骤后,重启虚拟机
# 1. 检查 CPU 标志位:
egrep -c '(vmx|svm)' /proc/cpuinfo
20
# 2. 再次检查 KVM 状态:
kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used
# 3. 检查内核模块是否加载:
lsmod | grep kvm
kvm_intel 569344 8
kvm 1445888 1 kvm_intel
irqbypass 16384 1 kvm
# 4. 如果上面都成功了,但 kvm-ok 还说权限问题;如果 egrep 有值,但 kvm-ok 提示权限问题,确保当前用户在 kvm 和 libvirt 组中:
sudo adduser $USER kvm
sudo adduser $USER libvirt
# 注销并重新登录 Ubuntu 使组权限生效
07.02 运行模拟器命令
如果要启动带窗口的版本,需要在ubuntu 桌面的虚拟机内部运行,不要用远程ssh 远程链接的窗口运行,否则可能会卡死或crash
emulator -no-snapshot -gpu swiftshader_indirect -memory 4096 -partition-size 4096
07.03 使用 scrcpy 在 远程 win10 上面显示 android模拟器的图形界面
07.03.01 在 虚拟机 ubuntu2024.04desktop(B) 上面建立与已经启动的android模拟器©的转发关系
# 1. 让 Guest(C) 系统的 adbd 监听 TCP 5555
adb -s emulator-5554 tcpip 5555
# 2. 将 Guest(C) 的 5555 转发到 Host 的 6666 端口
adb -s emulator-5554 forward tcp:6666 tcp:5555
6666
## adb:Android 调试桥工具。
## -s emulator-5554:指定目标设备(模拟器)。-s 表示选择特定设备,emulator-5554 是模拟器的序列号(通常表示第一个启动的模拟器)。
## forward:ADB 的子命令,用于建立端口转发隧道。
## tcp:6666:宿主机(你的电脑B:ubuntu2024.04desktop)上的监听端口。
## tcp:5555:目标设备(android模拟器)上的目标端口。
## 当你的电脑上有任意程序(浏览器、Postman、自定义脚本等)连接 127.0.0.1:6666 时,ADB 会悄悄将该连接"搬运"到模拟器内部的 127.0.0.1:5555。
## 前提条件:模拟器内部必须有一个服务正在监听 5555 端口,否则连接会返回 Connection refused。
## 单向转发 仅支持 宿主机 → 模拟器。若需反向(模拟器访问宿主机),应使用 adb reverse
## 非持久化 模拟器重启、ADB 服务重启或断开连接后,转发规则会失效,需重新执行
## 端口占用 宿主机 6666 端口不能被其他程序占用,否则命令会报错 cannot bind to socket
## 协议限制 此处均为 tcp:,ADB 也支持 localabstract:、localreserved:、jdwp: 等 Android 特有命名空间
# 3. 验证 Host(B:ubuntu2024.04desktop) 端口是否监听
ss -tlnp | grep -iE "6666|5555"
# ✅ 正常应显示:LISTEN 0 128 127.0.0.1:6666 0.0.0.0:* users:(("adb",pid=xxx,fd=x))
# 4. 确认 Host(B:ubuntu2024.04desktop) forward 规则存活
adb -s emulator-5554 forward --list
# 必须显示:emulator-5554 tcp:6666 tcp:5555
ss -tlnp | grep -iE "6666|5555"
LISTEN 0 5 127.0.0.1:5555 0.0.0.0:* users:(("qemu-system-x86",pid=68822,fd=58))
LISTEN 0 128 127.0.0.1:6666 0.0.0.0:* users:(("adb",pid=42231,fd=13))
LISTEN 0 5 [::1]:5555 [::]:* users:(("qemu-system-x86",pid=68822,fd=59))
# 5 常用forward命令
# 查看当前所有转发规则
adb forward --list
# 删除指定转发规则
adb forward --remove tcp:6666
# 删除所有转发规则
adb forward --remove-all
07.03.02 在开发机 Host(A:win10) 建立链接与虚拟机(B:ubuntu2024.04desktop)的 ssh 桥接
## https://github.com/Genymobile/scrcpy.git
## download https://github.com/Genymobile/scrcpy/releases/download/v3.3.4/scrcpy-win64-v3.3.4.zip
PS D:\install\scrcpy-win64-v3.3.4>
Write-Host "=== 清理旧隧道 ===" -ForegroundColor Cyan
Get-Process ssh -ErrorAction SilentlyContinue | Stop-Process -Force
Start-Sleep 2
::Write-Host "`n=== 重建隧道 (指向 6666) ===" -ForegroundColor Cyan, 0.0.0.0:5555 是其他用户可以链接B机器的5555端口
::把本机(执行命令的机器)的 5555 端口,映射到远程服务器(172.18.154.14)内部的 localhost (127.0.0.1) 的 6666 端口。(不是访问 172.18.154.14:6666)
::需要输入密码,独占一个窗口
ssh -N -f -o Compression=no -o TCPKeepAlive=yes -L 0.0.0.0:5555:127.0.0.1:6666 zfjvm01@172.18.154.14
Start-Sleep 3
Write-Host "`n=== 重启 ADB 并连接 ===" -ForegroundColor Cyan
taskkill /F /IM adb.exe 2>$null
Start-Sleep 2
.\adb start-server
.\adb connect 127.0.0.1:5555
Start-Sleep 2
.\adb devices
:: 在一个新窗口运行链接和scrcpy
PS D:\install\scrcpy-win64-v3.3.4> netstat -ano | findstr ":5555"
TCP 127.0.0.1:5555 0.0.0.0:0 LISTENING 37932
TCP 127.0.0.1:5555 127.0.0.1:55818 ESTABLISHED 37932
TCP 127.0.0.1:5555 127.0.0.1:55819 ESTABLISHED 37932
TCP 127.0.0.1:55818 127.0.0.1:5555 ESTABLISHED 41028
TCP 127.0.0.1:55819 127.0.0.1:5555 ESTABLISHED 41028
TCP [::1]:5555 [::]:0 LISTENING 37932
PS D:\install\scrcpy-win64-v3.3.4> .\adb connect 127.0.0.1:5555
already connected to 127.0.0.1:5555
PS D:\install\scrcpy-win64-v3.3.4> .\adb devices
List of devices attached
127.0.0.1:5555 device
emulator-5554 device
PS D:\install\scrcpy-win64-v3.3.4> .\scrcpy -s 127.0.0.1:5555
scrcpy 3.3.4 <https://github.com/Genymobile/scrcpy>
INFO: ADB device found:
INFO: --> (tcpip) 127.0.0.1:5555 device Car_on_x86_64_emulator
INFO: (tcpip) emulator-5554 device Car_on_x86_64_emulator
D:\install\scrcpy-win64-v3.3.4\scrcpy-serv...skipped. 13.8 MB/s (90980 bytes in 0.006s)
[server] INFO: Device: [unknown] Android Car on x86_64 emulator (Android 16)
INFO: Renderer: direct3d
INFO: Texture: 1408x792
:: 这个后面android模拟器中的界面就会在win10 上面显示出来
07.04 运行模拟器上面的app
## 在ubuntu2024.04desktop上面可以正常运行adb命令
adb devices
adb shell
点击 运行 WebView Browser Tester,输入 https://www.baidu.com/ 查看显示效果
会发现显示一下正常baidu页面后,出现如下内容(因为UA问题导致调用boxapp所致)
baiduboxapp://utils?action=sendIntent&minver=7.4¶ms=xxxxx
Webpage not available
The webpage at baiduboxapp://utils?
action=sendIntent&inver=7.4¶ms=%7xxxxx
could not be loaded because:
net::ERR_UNKNOWN_URL_SCHEME
可以采用输入如下url方式避免
https://www.baidu.com/?noapp=1
https://m.baidu.com
或者直接在ubuntu上面运行如下命令
adb shell am start -a android.intent.action.VIEW -d "https://m.baidu.com"
adb shell am start -a android.intent.action.VIEW -d "https://www.baidu.com/?noapp=1"
adb shell am start -a android.intent.action.VIEW -d "https://www.bilibili.com/h5/vehicle-web/v2"
# 停止以上界面
adb shell am force-stop org.chromium.webview_shell
可以使用自己指定的浏览器:
# 安装 Chrome (如果模拟器支持 GMS,自己下载chrome.apk)
adb install chrome.apk
# 启动 Chrome 并访问百度
adb shell am start -a android.intent.action.VIEW -d "https://www.baidu.com" -n com.android.chrome/com.google.android.apps.chrome.Main
B 备注
B01: 模拟器参数说明
emulator -no-snapshot -gpu swiftshader_indirect -memory 4096 -partition-size 4096
1. emulator
这是 Android SDK 或 AOSP 编译输出目录中的可执行文件路径。它负责加载系统镜像(system.img, vendor.img等)并在宿主机上创建一个虚拟设备。
2. -no-snapshot
含义:禁用快照功能。
作用:
默认情况下,模拟器会在关闭时保存当前状态(快照),下次启动时快速恢复。
使用此参数后,每次启动都是冷启动(Cold Boot),就像第一次开机一样,从头加载所有镜像文件。
为什么在开发中常用?
避免状态污染:在调试系统底层(如 AAOS HAL层、内核驱动)时,之前的错误状态可能会保留在快照中,导致难以复现 Bug。冷启动能确保环境干净。
节省磁盘空间/IO:快照文件可能很大,且读写频繁。禁用它可以减少磁盘 I/O 压力。
调试稳定性:有时快照恢复会导致图形渲染错误或内存泄漏,冷启动更稳定。
3. -gpu swiftshader_indirect
含义:指定 GPU 渲染模式为 SwiftShader(软件渲染),并使用间接模式。
背景:
Android 模拟器支持多种 GPU模式:auto, host, guest, swiftshader, angle 等。
host:使用宿主机的物理 GPU(最快,但需要驱动支持且容易崩溃)。
swiftshader:Google 开发的基于 CPU 的 OpenGL ES/Vulkan 软件实现。
为什么选这个?(关键点)
兼容性最强:在你的场景中(Win10 Host + Ubuntu Guest + 嵌套虚拟化可能未完美开启),物理 GPU 透传往往有问题,或者驱动程序不兼容 AAOS 的图形栈(Goldfish/VirtIO-GPU)。
避免黑屏/崩溃:AAOS 对图形要求较高,如果使用硬件加速(-gpu host)但驱动不支持,模拟器经常会黑屏、闪退或显示异常。swiftshader 虽然慢一点(因为用 CPU 算图形),但极其稳定,能保证界面正常显示。
Indirect:表示通过中间层进行渲染调用,进一步增加兼容性。
4. -memory 4096
含义:分配给模拟器的 RAM(内存)大小为 4096 MB (4 GB)。
作用:
Android 16 / AAOS 系统本身比较庞大,加上运行的应用和服务,2GB 内存通常不够用,会导致频繁的 OOM (Out Of Memory) 杀死进程或系统卡顿。
4GB 是一个比较舒适的起步值,能保证系统流畅运行。如果你的宿主机内存充足(如 16GB+),可以设置为 8192 (8GB) 以获得更好体验。
5. -partition-size 4096
含义:设置模拟器数据分区(userdata partition)的大小为 4096 MB (4 GB)。
作用:
默认的数据分区可能较小(如 550MB 或 2GB)。
AAOS 系统包含大量的日志、缓存、以及你可能安装的测试 APK。如果分区太小,很快就会提示"存储空间不足",导致无法安装应用或系统写入失败。
设置为 4GB 可以容纳更多的测试数据和日志。
06 其他尝试
# 尝试使用 VirtIO GPU (Linux KVM 环境下推荐)
emulator -no-snapshot -gpu virtio -memory 4096 -partition-size 4096
# 或者如果宿主机 GPU 支持良好,可以尝试 host
emulator -no-snapshot -gpu host -memory 4096 -partition-size 4096
07 后台运行:
如果你想在终端关闭后模拟器继续运行,可以加 -no-window(无界面)或通过 VNC/ADB 连接
B02 升级 aosp android16 webview版本
- 查找aosp16 上面 android webview的版本信息
根据 external/chromium-webview/Android.bp 的 release_package_webview_version
查找 grep -rn "soong_config_set.*webview.*release_package_webview_version" device/ vendor/ build/
得到 build/make/target/product/build_variables.mk:39:$(call soong_config_set, webview, release_package_webview_version, $(RELEASE_PACKAGE_WEBVIEW_VERSION))
再根据 RELEASE_PACKAGE_WEBVIEW_VERSION 查找 grep -rn "RELEASE_PACKAGE_WEBVIEW_VERSION" device/ build/
得到
build/make/target/product/build_variables.mk:39:$(call soong_config_set, webview, release_package_webview_version, $(RELEASE_PACKAGE_WEBVIEW_VERSION))
build/release/flag_values/bp4a/RELEASE_PACKAGE_WEBVIEW_VERSION.textproto:1:name: "RELEASE_PACKAGE_WEBVIEW_VERSION"
build/release/flag_values/trunk_staging/RELEASE_PACKAGE_WEBVIEW_VERSION.textproto:1:name: "RELEASE_PACKAGE_WEBVIEW_VERSION"
build/release/flag_values/bp2a/RELEASE_PACKAGE_WEBVIEW_VERSION.textproto:1:name: "RELEASE_PACKAGE_WEBVIEW_VERSION"
build/release/flag_declarations/RELEASE_PACKAGE_WEBVIEW_VERSION.textproto:1:name: "RELEASE_PACKAGE_WEBVIEW_VERSION"
分析上面找到的文件,得到对应的版本信息,如果需要升级或者降级对应代码线的webview版本信息,修改如下配置文件即可
cat build/release/flag_values/bp4a/RELEASE_PACKAGE_WEBVIEW_VERSION.textproto
name: "RELEASE_PACKAGE_WEBVIEW_VERSION"
value {
string_value: "134.0.6998.135"
}
cat build/release/flag_values/trunk_staging/RELEASE_PACKAGE_WEBVIEW_VERSION.textproto
name: "RELEASE_PACKAGE_WEBVIEW_VERSION"
value {
string_value: "140.0.7339.4"
}
cat build/release/flag_values/bp2a/RELEASE_PACKAGE_WEBVIEW_VERSION.textproto
name: "RELEASE_PACKAGE_WEBVIEW_VERSION"
value {
string_value: "133.0.6943.137"
}
cat build/release/flag_declarations/RELEASE_PACKAGE_WEBVIEW_VERSION.textproto
name: "RELEASE_PACKAGE_WEBVIEW_VERSION"
namespace: "webview"
description: "The version of WebView to include in the build"
value: {
string_value: "128.0.6613.88"
}
workflow: PREBUILT
containers: "product"
containers: "system"
- 升级 webview版本
模拟器中编译的x86_64版本,编译自己要升级的chromium webview对应的架构版本SystemWebview.apk(x86_64)架构版本
从 BUILD_ID=BP4A.251205.006 看出,上面编译的是 bp4a 版本,所以,要升级 webview,需要修改 build/release/flag_values/bp4a/RELEASE_PACKAGE_WEBVIEW_VERSION.textproto 对应的版本信息
修改参与编译的版本信息
vim build/release/flag_values/bp4a/RELEASE_PACKAGE_WEBVIEW_VERSION.textproto
name: "RELEASE_PACKAGE_WEBVIEW_VERSION"
value {
string_value: "146.0.7680.189"
}
添加对应的版本目录,复制 134.0.6998.135 为 146.0.7680.189,并且把自己编译的对应架构的SystemWebview.apk拷贝到 146.0.7680.189 下的对应目录
ls -l external/chromium-webview/
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 10 18:52 128.0.6613.88
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 10 18:52 133.0.6943.137
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 10 18:52 134.0.6998.135
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 10 18:52 136.0.7103.129
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 10 18:53 136.0.7103.35
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 10 18:53 136.0.7103.60
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 10 18:53 138.0.7204.67
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 10 18:53 140.0.7339.15
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 10 18:53 140.0.7339.4
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 10 18:53 141.0.7366.2
drwxrwxr-x 6 zfjvm01 zfjvm01 4096 4月 15 10:01 146.0.7680.189
-rw-rw-r-- 1 zfjvm01 zfjvm01 2269 4月 15 15:52 Android.bp
-rw-rw-r-- 1 zfjvm01 zfjvm01 2826 4月 10 18:53 CleanSpec.mk
-rw-rw-r-- 1 zfjvm01 zfjvm01 379 4月 10 18:53 METADATA
drwxrwxr-x 2 zfjvm01 zfjvm01 4096 4月 10 18:53 prebuilt
-rw-rw-r-- 1 zfjvm01 zfjvm01 29 4月 10 18:53 PREUPLOAD.cfg
-rw-rw-r-- 1 zfjvm01 zfjvm01 955 4月 10 18:53 README.md
-rw-rw-r-- 1 zfjvm01 zfjvm01 238 4月 10 18:53 TEST_MAPPING
ls external/chromium-webview/146.0.7680.189/
arm arm64 x86 x86_64
-
配置 external/chromium-webview/Android.bp
在 external/chromium-webview/Android.bp 增加 "android.test.base",,注释//"com.android.extensions.xr",
cat external/chromium-webview/Android.bp
...
webview_app_import {
name: "webview",
...
optional_uses_libs: [
"android.test.base",
"androidx.window.extensions",
"android.ext.adservices",
//"com.android.extensions.xr",
],
}否则编译 m -j$(nproc) webview 时,会出现如下错误
work-virtualization --bootclasspath-libs framework-wifi # hash of input list: dcbbf51b5be83621e97450158e990136f1aad731726dcd7dfcec21f286a3b93a
error: mismatch or misordering in the <uses-library> tags between the build system and the manifest:
- required libraries in build system: []
vs. in the manifest: []
- optional libraries in build system: [androidx.window.extensions, android.ext.adservices, android.test.base]
and missing ones in build system: [com.android.extensions.xr]
vs. in the manifest: [android.test.base, androidx.window.extensions, android.ext.adservices]
- tags in the manifest (external/chromium-webview/146.0.7680.189/x86_64/webview.apk):
uses-library-not-required:'android.test.base' uses-library-not-required:'androidx.window.extensions' uses-library-not-required:'android.ext.adservices'
note: the following options are available:
- to temporarily disable the check on command line, rebuild with RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" and disable AOT-compilation in dexpreopt)
- to temporarily disable the check for the whole product, set PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles
- to fix the check, make build system properties coherent with the manifest
- for details, see build/make/Changes.md and https://source.android.com/
devices/tech/dalvik/art-class-loader-context因为 Android 构建系统(Build System)中定义的"可选库列表"与 APK (webview.apk) AndroidManifest.xml中声明的 <uses-library>标签不一致。
// 严格匹配 Manifest 中的 <uses-library android:required="false" ... />
optional_uses_libs: [
"android.test.base", // Manifest 中有(增加)
"androidx.window.extensions", // Manifest 中有
"android.ext.adservices", // Manifest 中有
// com.android.extensions.xr // Manifest 中没有,所以这里也不要写!注释
],
- 重新编译 webview
m webview -j$(nproc)
或者 m superimage -j$(nproc)
- 查看chrome版本信息
strings libwebviewchromium.so | grep "Chrome/"
- 重新编译 webview
B03: 压缩HyperV 虚拟机的磁盘空间
B03.1 在 ubuntu2024.04desktop 内部压缩磁盘
#1. 创建一个填满零的大文件,直到磁盘满
sudo dd if=/dev/zero of=/zero.fill bs=1M status=progress
# 1398520414208 字节 (1.4 TB, 1.3 TiB) 已复制,435 s,3.2 GB/s
# dd: 写入 '/zero.fill' 时出错: 设备上没有空间
#2. 当提示"No space left on device"时,删除它
sudo rm /zero.fill
#3. 同步磁盘写入
sync
# 注意:这一步会让磁盘瞬间写满,可能会卡住几分钟,请耐心等待直到命令结束。
# 关闭 Ubuntu 虚拟机:
sudo shutdown now
# 必须完全关机,不能是休眠或保存状态。
# 另外可以清理系统
# o1. 清理过时的安装包
sudo apt autoclean
# o2. 移除无用的依赖包
sudo apt autoremove
# o3. 清理系统临时文件
sudo systemd-tmpfiles --clean
# o4. 清理旧日志
sudo journalctl --vacuum-time=7d
# o5. 如果磁盘空间紧张,可使用 ncdu 工具分析大文件:
sudo apt install ncdu
sudo ncdu /
# android16 磁盘空间占用
# zfjvm01@zfjvm0-vm:~/workspace/git/aosp16$ du -sh .repo
# 138G .repo
# zfjvm01@zfjvm0-vm:~/workspace/git/aosp16$ du -sh .
# 322G .
# zfjvm01@zfjvm0-vm:~/workspace/git/aosp16$ du -sh ../chromium/
# 85G ../chromium/
# du -sh out/DefaultSysArm64/
# 31G out/DefaultSysArm64/
B03.2 在win10 上面压缩 ubuntu2024.04desktop 磁盘
:: 管理员权限运行 Windows PowerShell
:: 找到 ubuntu2024.04desktop 磁盘路径 `D:\install\vms\VirtualHardDisks\hu2404tls01.vhdx`
:: 执行以下命令完全压缩磁盘
:: 导入 Hyper-V 模块
Import-Module Hyper-V
:: 执行压缩优化
Optimize-VHD -Path "D:\install\vms\VirtualHardDisks\hu2404tls01.vhdx" -Mode Full
::Hyper-V 压缩工具只能识别"全零"的空闲空间。你需要用零填充剩余的空闲空间,然后删除这个文件。

