移動開發中的模擬器(Emulator)與模擬器(Simulator)
本文主要涉及到兩個概念: Emulator 和 Simulator。通常我們在工作中可能統統習慣稱為“模擬器”,但實際上二者有所不同。為了分清概念,本文將 Emulator 譯作 “模擬器”, Simulator 譯作 “模擬器”。聽起來可能略拗口,如產生生理或心理不適,敬請諒解。
模擬器(Emulator),又稱模擬程式,在軟體工程中指可以使計算機或者其他多媒體平臺(掌上電腦,手機)能夠執行其他平臺上的程式,常被錯誤的稱為模擬器。模擬器多用於電視遊戲和街機,也有一些用於掌上電腦。模擬器一般需要ROM才能執行,ROM的最初來源是一些原平臺的ROM晶片,通過一些手段將原程式拷貝下來(這個過程一般稱之為“dump”)然後利用模擬器載入這些ROM來實現模擬過程。
模擬器(Simulator),又稱模擬程式,在計算機科學技術的軟體工程中,是指完全基於主機程式並模擬了目標處理器的功能和指令系統的程式。而模擬器(emulator)具有更強大的硬體模仿功能。
—— 轉引自 《simulator和emulator區別》
另外,原文標題為 “How Do Mobile Emulators Even?”,譯者根據正文內容,該而使用《移動開發中的模擬器與模擬器》作為標題。
正文部分:
每個移動開發者的專業生活都被許多瞬間所掌控,手指在鍵盤上滑動,耐心等待著螢幕上出現視窗,裡面有他/她已為之付出多時的的移動 App。結束一天的工作,這充滿希望的暫停讓他們的心情達到高潮,伴隨著一陣陣寬慰的嘆息(也可能是詛咒),因為移動模擬器(emulator)還算給力。
好的模擬器(emulator)對創造一個好的移動 App 來說至關重要。可是有人會問,什麼是模擬器,還是在移動環境中的?它們怎麼工作?為什麼有些模擬器比其他的要好?為什麼 Android he iOS 模擬器差別如此之大? 模擬器和模擬器之間到底有什麼區別?讓我們一起來看看。
模擬器和模擬器
首先來解決兩者之間的混淆。模擬器(emulator)“模仿執行二進位制程式碼的機器,而‘模擬器’通常指的是計算機模擬(computer simulation)”(wikipedia)。單詞“emulator” 1963 年由 IBM 創造,當時工程師們研發了使用“軟體、微指令和硬體組合”的產品。如果說,模擬器更像是虛擬機器,那麼模擬器(simulator)則只不過是模擬虛擬機器的軟體。
為了更好地理解兩者的差異,我直接上了 Telerik engineering —— 有疑惑的時候它總是解決問題的好去處。資深前端開發者 Kamen Bundev 不僅解釋了差異,還提供了簡短的歷史介紹:
模擬器是為桌面電腦 CPU 編譯的 OS(作業系統)版本,執行在虛擬機器內。Android 發展早期,OS 甚至都沒有為 x86 編譯版本,由虛擬機器模擬(emulating)整個 ARM CPU 架構,因此它慢了數十倍。現在,Apple 和 Google 都提供了 x86 虛擬機器映象(VM images),所以若 CPU 支援的話,虛擬機器會直接將多數呼叫傳給底層 CPU 和 GPU,從而更快地模擬相應的平臺。
因為模擬器是完整的 OS 虛擬機器,需要像在真實機器上一樣部署我們的 App,這也就意味著,部署起來,模擬器比模擬器花費的時間要多一些。
因此,使用模擬器和模擬器之間的最終權衡在在於速度與精確度之間的考量。模擬器僅僅是近似移動裝置。模擬器的功能則更加全面 —— 這可能包含著從模擬器內部呼叫移動裝置硬體的能力。與此同時,模擬器通常就是個殼 —— App 作為本地程式執行在電腦上,巢狀在框架以展示在不同裝置上的外觀。
有時候,模擬器對某些移動 App 來說已經基本足夠了(如電子書、2D 遊戲,商業基本業務線或教育領域的應用)。我早期進行移動開發時的經歷,實際上就是使用非常棒的 Corona SDK 模擬器,它提供了極其快的方式,在開發過程中獲取 App 粗糙快照,支援多種不同裝置的內容自適應:
不過,將 App 投入生產環境、裝到客戶的裝置上,模擬器也只能幫你這麼多了。
選擇對的工具
並非所有模擬器生來都一樣。每種框架的工程師們都傾向於,要麼選擇定製最適合的模擬器,要麼使用本地模擬器以便可以進行離線測(off-device testing)。基於 Cordova 的 hybrid 移動 App 跑在 WebView 中,它們很適合在自定義模擬器中測試,比如 Telerik Platform 中嵌有的基於 Web 的模擬器。這裡,App 僅僅是執行在 iframe 中,該 iframe 中注入了 Cordova core 以及一些 mock 的核心外掛,以便模擬真實功能。該模擬器甚至還包含模擬硬體工具如設定定位的工具:
此外,通過在網頁中呈現模擬效果,使用者可以使用 Chrome 或者 Safari 等內建的開發者工具,通過控制檯檢查程式碼、偵測問題。
其他 hybrid 移動 App 框架也都有類似的可靠的模擬器選項,在小的瀏覽器視窗中執行。Ionic 和 Telerik AppBuilder(如前文中圖片所示)就是很棒的案例。使用 Web 技術構建的移動 App 可能是最容易模擬的。
功能全面的 IDE,同樣可能提供內建的模擬器和模擬器,以使移動開發者的工作流程得到舒緩。一個出色的例子是 Visual Studio 的知名模擬器,它同樣可以在像 Eclipse 等其他 IDE 中獲取。另一個不錯的例子是 AppBuilder 的桌面客戶端模擬器,它是內建的,並且在儲存之後使用 LiveSync:
如果是那些並非跑在 WebView 中的非 hybrid 的移動 App 呢?不使用真實裝置,開發者如何有效率地模擬 App?
iOS 花園
開發者們可以使用的新的 “Javascript Native” 工具鏈、執行時和框架 —— 包括 Titanium、React Native、Fuse 以及 NativeScript —— 已經壓縮了開發者對模擬器速度合理預期的邊界。這些工具“利用 JavaScript 虛擬機器解釋 JavaScript 程式碼,並且……將程式碼編譯為可以構建 App 使用者介面的原生 API”。其所構建的 App 可以在原生模擬器中模擬,並且能夠通過如 NativeScript 的 CLI 工具開發,當開發者使用諸如 tns emulate ios or tns livesync ios --watch 這樣的命令構建的時候使用這些原生模擬器。
假如我們使用這些 JavaScript Native 工具開發 App 嚴重依賴於原生模擬器的話,生活就被這些低水平的(sub-par)原生模擬器嚴重影響了。對於擁有裝著 Xcode 的 Mac 的開發者來說,Xcode 模擬器是在開發程序獲取 App 準確模樣的完全可以接受的、相當快的方式。
Xcode 模擬器是一款 Mac 應用,可以執行為之特別構建的二進位制碼。可以使用它測試 App 在裝置上的幾乎所有的預期功能。需要注意,例外的是那些特定硬體的元素無法在 Mac 上測試,比如說 iPhone 的加速度計和 GPS 功能。
在核心部分中,當你為 Xcode 模擬器構建應用的時候,Xcode 拿到程式碼並將其編譯,建立一個 .ipa 檔案,應用被設定為在 MacOSX 上執行,該檔案可以執行在 i386 處理器中,iPhone/iPad/iPod 模擬器全都是 i386。因此,程式碼執行在為 i386 構建的模擬器上,而不是 ARM,ARM 是在真機裝置上執行所需的。還有一條底線,Xcode 模擬器被設計來執行在 Mac 上像 iPhone 一樣工作,但永遠沒法和 iPhone 真實體驗相比。雖然也挺接近了。
Android 的沼澤
不過對 Android 來說,水可相當髒了。為什麼會有這麼多不同種類的 Android 模擬器,以至於需要不斷重造輪子?和不包含任何模擬 ARM 處理器企圖的 Xcode 模擬器不同的是,Android 模擬器走了一條不同的路,它使用了一個聽起來略諷刺的名字(但是開源的)“Quick EMUlator。
Android 模擬器基於 QEMU(Quick EMUlator),QEMU (使用 KVM,一個只在 Linux 可用的基於核心的虛擬機器)在你的 x86 處理器的電腦上模擬 AMR 處理器。我當然不需要解釋,為何通過軟體模擬處理器並不是好主意,如果你想要反應快還可用的話。(來源:http://wiki.qemu.org/Main_Page)
Android 模擬器是慢出了名的。所有 Android 開發者都在觀眾或者客戶面前碰到過這樣尷尬的時刻,原生的 Android 模擬器(Android Virtual Device, 簡稱 AVD)沒法啟動了,或者簡直慢到讓人痛苦,等待的過程都能說段單口相聲了。所有處理 Android 構建的框架都需要將 Android 模擬器糟糕的效能納入考慮。
比如說, Xamarin 使用原生的 Xcode 模擬器,也能使用原生的 Android 模擬器,不過會提示它很慢,提供一些加速的小訣竅,並請求使用者耐心等待:
模擬器啟動需要一段時間,在它啟動完成之前,您可以考慮將它放在一邊去做點別的事情。重新部署 App 也不需要關閉模擬器……執行時安裝可能需要一段時間,請您耐心等待。
他們還打包了他們自己的 Android 模擬器,叫做 Xamarin Player。
一些 Titanium 開發者寫了一篇很棒的博文,討論如何利用 Intel 的 HAXM (Hardware Accelerated Execution Manager,硬體加速執行管理器)來替代 KVM 進行機器模擬。HAXM 確實讓情況好了一點。
不過,一些開發者在 App 測試時已轉向完全不同的 Android 模擬器;我個人比較喜歡 Genymotion(見下圖),它是基於 VirtualBox 模擬器的。
僅僅使用模擬器還不夠的時候
在某個時間點,通常是 App 開發週期的晚中階段,放開模擬器、模擬器,將你的 App 裝到越多越好的裝置上去,這很重要。側裝(side-loading)到 Android 上,使用作為外殼的輔助 App,針對 iPhone 做完整的開發配置或進行私有釋出,這些都是合理的測試方法。希望理解模擬器如何工作以及作為移動 App 開發者它們在何處融入你的生活,能幫你緩解等待模擬器啟動、部署安裝時的痛苦。同時,深呼吸!