Android 模拟器:Project Marble 中的改进

本文介绍了如何通过五项改进措施优化Android模拟器的性能,包括调整默认电池模式、实现模拟器暂停/恢复功能、减少绘制调用开销、降低macOS上主循环的IO开销以及引入Headless构建模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在减少开销的同时保持原本设计原则

Android 模拟器的最大好处在于为开发者提供了一种可扩展的方法,通过各种设备配置和屏幕分辨率来测试最新 Android API,而无需为每个配置购买物理设备。因此,在 Android 模拟器上测试应用程序应该尽可能贴近在物理设备上的测试,并同时保持虚拟设备的优势。

为了支持最新的系统映像,我们特意设计一个尽可能接近物理设备的 Android 模拟器,而不只是一个仿真器,这种方法可以确保 API 的正确性以及 Android 系统行为和交互的高保真度。当一个新的 Android 版本推出时,我们只需要确保我们的硬件抽象层(HALs)和内核与模拟器和新的系统映像兼容,而不需要从头开始为新的 Android 版本重新实现 Android API 中的所有更改。这种体系结构最终大大地加快了模拟器采用新的系统映像的速度。

然而,这种完整的系统模拟方法在 CPU 周期和内存访问上的开销都会增加。相比之下,基于模拟器的方法在主机系统上包装类似的 API,开销可能会更低。因此,我们的挑战在于,在降低 CPU 和内存开销的同时,保持完整系统模拟的准确性和维护优势。

对 Android 模拟器架构的研究

Android 模拟器在称为 Android 虚拟设备(AVD)的虚拟机上运行 Android 操作系统。AVD 包含了完整的 Android 软件栈,运行时就像在物理设备上一样。总体架构图如下。

**Android Emulator System Architecture**

 

由于整个 Android 操作系统的运行和主机的操作系统完全分离,因此运行 Android 模拟器可能会导致主机机器上的后台活动,即便没有任何输入。在进行了一些技术调查之后发现,当 AVD 空闲时,如下一些任务是 CPU 周期的主要消耗者:

  • Google Play Store —— 当有新版本时,应用程序会自动更新。
  • 后台服务 —— 当它认为设备在充电时,一些响应式的服务会使 CPU 使用率保持在较高水平。
  • 动画 —— 例如实况壁纸

对于这些领域我们进行了更深入的技术研究并找到了以下 5 个解决方案来优化 Android 模拟器。

  1. 默认电池模式
  2. 模拟器的暂停/恢复
  3. 减少绘制调用的开销
  4. 减少 macOS 上主循环的 IO 开销
  5. Headless 构建

改进 #1 —— 默认电池模式

之前,Android 模拟器把 AVD 的电池模式设置为充电模式。经过深思熟虑的讨论和数据分析,我们得出结论,最好将 AVD 默认设置为电池模式。因为大多数 Android framework,服务和应用程序都经过了优化以节省电池寿命,这些优化都只在设备(物理设备或虚拟设备)认为它在使用电池而不是充电时才开始。

然而,仅仅默认 AVD 使用电池还不够。因为处于电池模式会导致屏幕在一段时间之后自动关闭。这对于在笔记本电脑或者台式机上使用 Android 模拟器的用户来说会有一点困惑,因为他们期望应用程序不会随机进入睡眠状态,需要被唤醒。为了防止这种情况,Android 模拟器将在每次冷启动完成时用 ADB shell 命令将屏幕关闭的时间设置为最大值(~24 天)。

有了这些改变,Google Play Store 不会在电池模式再自动更新应用程序,避免了系统开销。然而,在切回充电模式之后,[应用程序的自动升级] (support.google.com/googleplay/…) 仍然可以被触发。这实际上让开发者可以控制何时自动更新应用程序。这可以防止对关键用例的干扰,比如当用户只想构建和测试单个应用程序的时候。下表比较了电池模式和充电模式下的 CPU 使用状况:

**AVD CPU Usage: Auto-update app vs Idle**

改进 #2 —— 模拟器暂停/恢复

在很多情况下,你可能需要立即保证模拟器不会在关键任务期间(比如编辑/生成/部署)在后台占用 CPU 周期。为了解决这个问题,我们正在研究一个控制台命令和接口,用于完全暂停模拟器 CPU 的使用。这可以通过以下控制台命令显示暂停/恢复 AVD 来完成。

**Android Emulator: Pause command line options**

 

这里的挑战是如何协调 Android Studio 和 Android 模拟器状态的改变。所以当在部署应用程序时,我们会自动恢复模拟器。我们还在研究这个机制,很高兴听到您的想法和反馈

改进 #3 —— 减少绘制调用的开销

我们还对 Android 模拟器的引擎进行了修改,使其更高效的绘图,从而在测试屏幕上有很多对象的图形密集型应用程序时获得更流畅的用户体验。比如,模拟器 v28.1.10 在GPU 模拟压力测试应用程序上的绘制速度比 v28.0.23 提升了 8%。我们还在 Android Q 上进行进一步的优化,并将在 Android Q preview 期间共享其他更新。

**Emulator OpenGL ES FPS: 28.0.23 vs 28.1.10**

 

改进 #4 —— 减少 macOS 上主循环的 IO 开销

完整的系统模拟器必须维护一些方法,以通知虚拟操作系统磁盘和网络上的 I/O 已经完成。Android 模拟器基于 QEMU,使用主循环和 IO 线程来做到这一点。这在 Linux 和 Windows 上的开销都比较低。然而在 macOS 上我们看到,由于使用了 select() 系统调用,主循环的 CPU 使用率更高。这通常没有高效的实现方式。macOS 提供了一个低开销的方式来等待 I/O:kqueue。我们发现当前基于 select() 主 I/O 循环,可以替换为基于 kqueue 的主 I/O 循环。这大幅降低了主循环中的 CPU 使用率,从 10% 降低到 3%。由于这并不能说明所有空闲 CPU 使用率的情况,下面的图表没有显示太多的变化。然而,这种差异仍然是可以观察到的。

AVD Idle CPU Usage — Emulator 28.0.23 vs 28.1.10

 

改进 #5 —— Headless 构建

对于那些在 Android 应用程序构建中使用持续集成系统的用户,我们也在这方面进行了性能改进。通过关闭 Android 模拟器的用户界面,您可以使用新的模拟器 Headless 模式。这种新的模式在后台运行测试,并使用更少的内存。它大概还需要 100MB,主要是因为我们在用户界面使用的 Qt 库没有加载。当不需要用户界面和交互时,这也是运行自动化测试的一个好选择。增量可以类似如下那样启动两个模拟器 AVD 实例来测量。注意,命令行示范显式地指定主机的 GPU 模式,以确保在相同的条件下进行比较。

**Android Emulator: Headless emulator command line option**

 

 

**AVD Idle Memory Usage — emulator vs emulator-headless**

最后

如果你看到了这里,觉得文章写得不错就给个赞呗!欢迎大家评论讨论!如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足,定期免费分享技术干货。谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值