docker-android Android 17 支持与编译修改
Android 17(API 37.0)因上游 emulator/系统镜像 bug 无法稳定运行,已放弃,改用 Android 16(API 36)。本文档记录完整过程。
Android 17 与 Android 16 的区别点
| 维度 | Android 17 (API 37) | Android 16 (API 36) |
|---|---|---|
| 系统镜像包路径 | system-images;android-37.0;… | system-images;android-36;… |
| (API 37 起带 minor 版本后缀) | (无后缀) | |
| CLI API_LEVEL 值 | “17.0”: “37.0”(必须带 .0) | “16.0”: “36” |
| emulator 版本 | 37.1.11 | 37.1.11(相同) |
| mapper.ranchu 读回 bug | 有(API 33~36 均无,37.0/37.1 有) | 无 |
| SurfaceFlinger 崩溃 | 有(崩溃循环) | 无 |
| 触摸输入 | 需 -screen multi-touch | 需 -screen multi-touch |
| DISABLE_SYSTEM_UI | 需要(否则崩溃循环) | 不需要(SystemUI 完整) |
| 任务快照崩溃 | 有(间歇) | 无 |
| scrcpy / screencap | 不可用(MediaCodec 0xffffffe0) | 可用(编码器正常) |
| SwiftShader Vulkan | 有 SIGSEGV(需 -feature -Vulkan) | 同(同样需该修复) |
| 稳定性 | 不稳定,无法长期使用 | 稳定(Chrome 压力 0 崩溃) |
| 镜像体积 | 6.7GB | 6.64GB |
核心差异:mapper.ranchu gralloc bug(仅 API 37 存在)。其余修改
(多阶段构建、-screen multi-touch、-feature -Vulkan、自愈)两个版本共用。
Android 17 遇到的问题:日志表现 / 尝试修改 / 效果
【问题 1】SurfaceFlinger 崩溃循环(“模拟器一直重启”)
日志表现:
F mapper.ranchu: Assertion failed: !rcEnc->featureInfo()->hasReadColorBufferDma
F libc: Fatal signal 6 (SIGABRT) … tid (RegionSampling), pid (surfaceflinger)
#03 mapper.ranchu.so GoldfishMapper::readFromHost
#09 system/bin/surfaceflinger RegionSamplingThread::threadMain
且 init 连带 SIGKILL zygote -> framework 每 20~90 秒整体重启
尝试修改:
- DISABLE_SYSTEM_UI=true(CLI _disable_system_ui_if_needed):
boot 后 pm disable-user + pm disable + stop/start 重启 framework - 排查 GPU 模式:-gpu host 永不 boot;swiftshader/swangle 可 boot 但间歇崩
- 排查特性开关:-feature -GLDMA,-GLDMA2,-GLDirectMem 无效
(gfxstreamFeature:GlDma=0 但 hasReadColorBufferDma 依旧为真)
效果:
禁用 SystemUI 后崩溃从约 1 次/14s 降到 0(主触发源=导航栏亮度采样监听)。
有效但不彻底——任务快照(问题 2)仍会间歇触发。
【问题 2】任务快照间歇崩溃
日志表现:
F DEBUG : Executable: /system/bin/app_process64 Cmdline: system_server
name: TaskSnapshotPer >>> system_server <<<
Abort message: ‘Assertion failed: !rcEnc->featureInfo()->hasReadColorBufferDma’
(打开/切换 App,尤其 Chrome 时触发)
尝试修改:
- 关闭动画(window/transition/animator_duration_scale=0)-> 无效
- config_disableTaskSnapshots 是系统镜像编译期配置,无运行时开关
- setTaskSnapshotEnabled Binder 为 @hide 且重启失效
效果:无法规避。间歇性(非每次必现),靠 Android init 自愈 + CLI 自愈兜底。
【问题 3】触摸输入无效
日志表现:
adb shell getevent -p 只有 qwerty2 键盘 / AT 键盘 / Power Button,无触摸设备;
config.ini hw.screen=multi-touch 被降级为 touch 时 emulator 不创建触摸设备
尝试修改:deploy() 参数加 -screen multi-touch
效果:有效。创建 virtio_input_multi_touch_* 设备,X 点击 -> guest
ABS_MT_TRACKING_ID down/up 事件正常。(该修复对 16 同样生效)
【问题 4】scrcpy / screencap 不可用
日志表现:
adb shell screencap -p -> exit 134(SIGABRT,同一断言)
scrcpy -> MediaCodec$CodecException: Error 0xffffffe0
C2SoftAvcEnc::process -> C2AllocationGralloc::map -> readFromHost
尝试修改:
- scrcpy --video-encoder=c2.android.avc.encoder / --no-audio / 换编码器 -> 均无效
- -feature -GLDMA,-GLDMA2,-GLDirectMem -> 无效
效果:无法规避。编码器/截屏都走 gralloc 读回路径,等上游修复。
【问题 5】CPU 异常高
日志表现:ps -o %cpu 显示 494% / 630%
根因:ps -o %cpu 是生命周期平均值,被崩溃循环 + boot 空转拉高
排查:用 /proc//stat 瞬时采样,实际稳定 ~40%(与 API 34 相当)
效果:确认是测量假象 + 崩溃循环伴生,非独立问题。
【问题 6】网络"没网"
日志表现:
adb shell ping 8.8.8.8 -> “connect: Network is unreachable”
wpa_supplicant 反复 CTRL-EVENT-BEACON-LOSS
根因:容器本身网络正常(wget 实测通);guest wifi 关联需几分钟(beacon-loss),
且每次 framework 崩溃重启都会掉线重连 -> 看起来"没网"
效果:崩溃修复 + 等待关联后稳定,ping 0% 丢失。
【问题 7】SwiftShader Vulkan SIGSEGV(与 16 共有)
日志表现:
CLI 日志 emulator process exited unexpectedly (exit code -11)(SIGSEGV)
崩溃前有 VkInstance … application:‘Chromium’
third_party/SwiftShader/… UNSUPPORTED: curExtension 告警
根因:emulator 37.1.11 的 SwiftShader Vulkan 实现 bug(宿主机侧,非系统镜像)
尝试修改:deploy() 加 -feature -Vulkan 禁用 guest Vulkan
效果:有效。Chrome 退回 GLES 路径,压力测试 0 次 SIGSEGV。
上游模拟器的问题(上游支持了再继续)
-
根因(guest 与 host 版本错配)
emulator 37.1.11 的 gfxstream host 后端广播 ReadColorBufferDMA 特性,
但 API 37.0 / 37.1 系统镜像的 mapper.ranchu gralloc HAL 编译时预期该特性
关闭(未实现 DMA 读回路径),于是任何颜色缓冲读回都触发断言崩溃。 -
受影响能力
- SurfaceFlinger 崩溃循环(RegionSampling 亮度采样)
- 任务快照(TaskSnapshotPersister)
- screencap / scrcpy(编码器与截屏读回)
- 整体稳定性(framework 周期性重启)
-
已排除的方向
- GPU 模式无关:host 永不 boot;swiftshader / swangle / angle 均可复现
- 特性开关无效:-feature -GLDMA,-GLDMA2,-GLDirectMem、-HostComposition
- 替代镜像不可用:aosp_atd 最高只到 API 36;
google_apis_playstore 的 37.x 仅有 ps16k(16KB 页)变体;
android-37.1 也是 ps16k
-
上游参考
LibreMediaConverter 项目的 API 37 崩溃复现报告(7 组 GPU 矩阵、排除项):
https://github.com/JMR-dev/LibreMediaConverter/blob/main/docs/api-37-emulator-crash.md -
恢复条件(满足其一即可重新尝试 Android 17)
- Google 发布修复该问题的 android-37.x 新系统镜像(用 -gpu host 能 boot)
- 或 emulator gfxstream 后端修复 ReadColorBufferDMA 广播
- 或出现 API 37 的 aosp_atd / google_atd 精简镜像
验证方法:启动后 logcat 无 ReadColorBufferDMA 断言、scrcpy 可用、
Chrome 快速返回不崩溃。
-
恢复时需要注意
- SDK 包路径带 minor 版本:必须用精确路径 android-37.0(避免命中 beta)
- -screen multi-touch(触摸)、-feature -Vulkan(SIGSEGV)仍需保留
- DISABLE_SYSTEM_UI 可作为 opt-in,但最好在上游修复后回归验证是否需要
- 容器重建会清空 /data,应用目录需重新初始化
更多推荐
所有评论(0)