[譯]Android 模擬器:Project Marble 中的改進

這是 Android Studio 團隊一系列博客文章中第三篇,深刻探討了 Project Marble 中的細節和幕後狀況。本文是由模擬器團隊的 Sam Lin(產品經理),Lingfeng Yang(技術主管)和 Bo Hu(技術主管)撰寫的。html

今天咱們很高興地向您介紹咱們在 Project Marble 期間在 Android 模擬器上取得的最新進展。咱們的核心目標之一是使 Android 模擬器成爲應用程序開發的必選設備。物理 Android 設備很是棒,但咱們的目標是增長功能和性能,使您在開發和測試 Android 應用程序時更加高效。前端

咱們據說不少應用程序開發者喜歡咱們最近對模擬器所作的改進,從 2 秒的啓動時間,GPU 圖形加速,再到屏幕快照。然而,咱們也據說 Android 模擬器消耗了您開發電腦上的太多系統資源。爲了解決這個問題,咱們在 Project Marble 中建立了一個任務來優化 Android 模擬器的 CPU 使用率。在過去幾個月的 Project Marble 中,在不違背本來設計原則的狀況下,Android 模擬器的能效和繪製速度有了顯著提高。在本文中,咱們將介紹到目前爲止在 Canary Channel 上 Android Emulator 28.1 發佈的一些進展。android

在減小開銷的同時保持本來設計原則

Android 模擬器的最大好處在於爲開發者提供了一種可擴展的方法,經過各類設備配置和屏幕分辨率來測試最新 Android API,而無需爲每一個配置購買物理設備。所以,在 Android 模擬器上測試應用程序應該儘量貼近在物理設備上的測試,並同時保持虛擬設備的優點。ios

爲了支持最新的系統映像,咱們特地設計一個儘量接近物理設備的 Android 模擬器,而不僅是一個仿真器,這種方法能夠確保 API 的正確性以及 Android 系統行爲和交互的高保真度。當一個新的 Android 版本推出時,咱們只須要確保咱們的硬件抽象層(HALs)和內核與模擬器和新的系統映像兼容,而不須要從頭開始爲新的 Android 版本從新實現 Android API 中的全部更改。這種體系結構最終大大地加快了模擬器採用新的系統映像的速度。git

然而,這種完整的系統模擬方法在 CPU 週期和內存訪問上的開銷都會增長。相比之下,基於模擬器的方法在主機系統上包裝相似的 API,開銷可能會更低。所以,咱們的挑戰在於,在下降 CPU 和內存開銷的同時,保持完整系統模擬的準確性和維護優點。github

對 Android 模擬器架構的研究

Android 模擬器在稱爲 Android 虛擬設備(AVD)的虛擬機上運行 Android 操做系統。AVD 包含了完整的 Android 軟件棧,運行時就像在物理設備上同樣。整體架構圖以下。shell

因爲整個 Android 操做系統的運行和主機的操做系統徹底分離,所以運行 Android 模擬器可能會致使主機機器上的後臺活動,即使沒有任何輸入。在進行了一些技術調查以後發現,當 AVD 空閒時,以下一些任務是 CPU 週期的主要消耗者:

  • Google Play Store —— 當有新版本時,應用程序會自動更新。
  • 後臺服務 —— 當它認爲設備在充電時,一些響應式的服務會使 CPU 使用率保持在較高水平。
  • 動畫 —— 例如實況壁紙

對於這些領域咱們進行了更深刻的技術研究並找到了如下 5 個解決方案來優化 Android 模擬器。後端

  1. 默認電池模式
  2. 模擬器的暫停/恢復
  3. 減小繪製調用的開銷
  4. 減小 macOS 上主循環的 IO 開銷
  5. Headless 構建

改進 #1 —— 默認電池模式

以前,Android 模擬器把 AVD 的電池模式設置爲充電模式。通過深思熟慮的討論和數據分析,咱們得出結論,最好將 AVD 默認設置爲電池模式。由於大多數 Android framework,服務和應用程序都通過了優化以節省電池壽命,這些優化都只在設備(物理設備或虛擬設備)認爲它在使用電池而不是充電時纔開始。android-studio

然而,僅僅默認 AVD 使用電池還不夠。由於處於電池模式會致使屏幕在一段時間以後自動關閉。這對於在筆記本電腦或者臺式機上使用 Android 模擬器的用戶來講會有一點困惑,由於他們指望應用程序不會隨機進入睡眠狀態,須要被喚醒。爲了防止這種狀況,Android 模擬器將在每次冷啓動完成時用 ADB shell 命令將屏幕關閉的時間設置爲最大值(~24 天)。網絡

有了這些改變,Google Play Store 不會在電池模式再自動更新應用程序,避免了系統開銷。然而,在切回充電模式以後,[應用程序的自動升級] (support.google.com/googleplay/…) 仍然能夠被觸發。這實際上讓開發者能夠控制什麼時候自動更新應用程序。這能夠防止對關鍵用例的干擾,好比當用戶只想構建和測試單個應用程序的時候。下表比較了電池模式和充電模式下的 CPU 使用情況:

改進 #2 —— 模擬器暫停/恢復

在不少狀況下,你可能須要當即保證模擬器不會在關鍵任務期間(好比編輯/生成/部署)在後臺佔用 CPU 週期。爲了解決這個問題,咱們正在研究一個控制檯命令和接口,用於徹底暫停模擬器 CPU 的使用。這能夠經過如下控制檯命令顯示暫停/恢復 AVD 來完成。

這裏的挑戰是如何協調 Android Studio 和 Android 模擬器狀態的改變。因此當在部署應用程序時,咱們會自動恢復模擬器。咱們還在研究這個機制,很高興聽到您的想法和反饋

改進 #3 —— 減小繪製調用的開銷

咱們還對 Android 模擬器的引擎進行了修改,使其更高效的繪圖,從而在測試屏幕上有不少對象的圖形密集型應用程序時得到更流暢的用戶體驗。好比,模擬器 v28.1.10 在GPU 模擬壓力測試應用程序上的繪製速度比 v28.0.23 提高了 8%。咱們還在 Android Q 上進行進一步的優化,並將在 Android Q preview 期間共享其餘更新。

改進 #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 使用率的狀況,下面的圖表沒有顯示太多的變化。然而,這種差別仍然是能夠觀察到的。

改進 #5 —— Headless 構建

對於那些在 Android 應用程序構建中使用持續集成系統的用戶,咱們也在這方面進行了性能改進。經過關閉 Android 模擬器的用戶界面,您可使用新的模擬器 Headless 模式。這種新的模式在後臺運行測試,並使用更少的內存。它大概還須要 100MB,主要是由於咱們在用戶界面使用的 Qt 庫沒有加載。當不須要用戶界面和交互時,這也是運行自動化測試的一個好選擇。增量能夠相似以下那樣啓動兩個模擬器 AVD 實例來測量。注意,命令行示範顯式地指定主機的 GPU 模式,以確保在相同的條件下進行比較。

接下來

要使用本文中介紹的性能和資源優化,請在 Canary Channel 下載 Android Emulator 28.1。咱們很高興能與您分享此次提早的進展,但咱們確定尚未完成。咱們今天邀請您嘗試 Android Emulator 的最新更新,並向咱們發送您的反饋

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索