女友靈魂一問:鴻蒙OS如何實現(xiàn)跨平臺?
周末在家休息,女朋友在刷朋友圈,突然她問我:最近我的朋友圈經常被華為刷屏,到底什么是“鴻蒙”啊?
圖片來自 Pexels
鴻蒙 OS 回顧
2019 年 8 月 9 日華為開發(fā)者大會上,華為消費者業(yè)務 CEO 余承東正式宣布發(fā)布自有操作系統(tǒng)鴻蒙,內核為 Linux 內核、鴻蒙微內核和 LiteOS。未來將擺脫 Linux 內核和 LiteOS,只有鴻蒙微內核。
鴻蒙(英語:Harmony OS,開發(fā)代號 Ark)是華為自 2012 年開發(fā)的一款可能兼容 Android App 的跨平臺操作系統(tǒng)。

圖:鴻蒙 OS 的四大技術特性
鴻蒙 OS 的四大技術特性如下:
- 分布式架構首次用于終端 OS,實現(xiàn)跨終端無縫協(xié)同體驗。
- 確定時延引擎和高性能 IPC 技術實現(xiàn)系統(tǒng)天生流暢。
- 基于微內核架構重塑終端設備可信安全。
- 通過統(tǒng)一 IDE 支撐一次開發(fā),多端部署,實現(xiàn)跨終端生態(tài)共享。
什么是跨平臺
在以前,平臺≈操作系統(tǒng)。所以,傳統(tǒng)意義上的跨平臺即不依賴于操作系統(tǒng),也不依賴硬件環(huán)境。一個操作系統(tǒng)下開發(fā)的應用,放到另一個操作系統(tǒng)下依然可以運行。
但是隨著科技的發(fā)展,平臺≈操作系統(tǒng)已經不成立了,就像華為推出的鴻蒙 OS,他可以支持到多種多樣的設備,如手機、手表、電腦、汽車、智能家居設備等。

所以,今天我們談的跨平臺,指的是跨設備。即平臺≈設備。

所以,華為希望鴻蒙 OS 可以運行在各種各樣的設備上,所以,鴻蒙 OS 必然需要具備跨平臺的能力。
而且,鴻蒙想要做的不僅僅是操作系統(tǒng)可以跨平臺,更重要的是要讓用戶和開發(fā)者真正的感受到跨平臺。
所以,跨平臺操作系統(tǒng)鴻蒙的目的是:使開發(fā)者能夠聚焦自身業(yè)務邏輯,像開發(fā)同一終端一樣開發(fā)跨終端分布式應用,也使最終消費者享受到強大的跨終端業(yè)務協(xié)同能力為各使用場景帶來的無縫體驗。
Java 實現(xiàn)跨平臺
先來說說 Java 是如何實現(xiàn)跨平臺的。Java 對于跨平臺的支持,就像對安全性和網絡移動性的支持一樣,是分布在整個 Java 體系結構中的。
其中扮演著重要角色的有 Java 語言規(guī)范、Class 文件、Java 虛擬機(JVM)等。
首先,在 Java 語言規(guī)范中,規(guī)定了 Java 語言中基本數(shù)據(jù)類型的取值范圍和行為。
其次,所有 Java 文件要編譯成統(tǒng)一的 Class 文件。最后,通過 Java 虛擬機將 Class 文件轉成對應平臺的二進制文件。
Java 的平臺無關性是建立在 Java 虛擬機的平臺有關性基礎之上的,是因為 Java 虛擬機屏蔽了底層操作系統(tǒng)和硬件的差異。
想要運行一段 Java 代碼,要經過多個步驟,將 Java 源代碼轉換成機器可以執(zhí)行的機器代碼,這個過程主要由虛擬機來完成。
在著名的 HotSpot 虛擬機中,主要有解釋執(zhí)行和即時編譯兩種形式:
- 解釋執(zhí)行,逐條將字節(jié)碼翻譯成機器碼并執(zhí)行。
- 即時編譯(Just-in-time ,JIT),將一個方法中包含的所有字節(jié)碼編譯成機器碼后再執(zhí)行。
HotSpot 默認采用混合模式,綜合了解釋執(zhí)行和即時編譯兩者的優(yōu)點。它會先解釋執(zhí)行字節(jié)碼,而后將其中反復執(zhí)行的熱點代碼(熱點檢測),以方法為單位進行即時編譯。
Android 實現(xiàn)跨平臺
Android 其實基于 Java 語言的,所以同理,想要運行一段 Android 代碼,也要經過多個步驟,將 Android 源代碼轉換成機器可以執(zhí)行的機器代碼。
但是這個轉換過程在 Android 的不同版本中實現(xiàn)不盡相同:
Android 1.0(2008 年):采用一個名為 Dalvik 的虛擬機,并且集成了一個解釋器。當 App 運行時,就會調用這個解釋器,對代碼進行逐句解釋,速度很慢。
Android 2.2(2010 年):引入 JIT(Just In Time)即時編譯機制,當 App 運行時,會將用戶經常使用的功能編譯為機器能直接執(zhí)行的 010101 機器碼,不用一句一句地去翻譯。
當出現(xiàn)不常用的功能時,再調用解釋器來翻譯;這樣速度加快,但每次啟動 App 都要重新編譯一次,不能一勞永逸。
Android 5.0(2014 年 10 月):將虛擬機 Dalvik 換成 ART(Android Run Time),將 JIT 的編譯器替換成 AOT(Ahead of Time)。
如此,App 在下載后安裝到手機上時同時把能編譯的代碼先編譯成機器聽得懂的 101010;剩下不太好翻譯的代碼,就在用戶使用時再叫醒解釋器來翻譯。
如此,不用每次打開 App 都需要編譯,但安裝 App 的時間有點長,而且占用手機空間。
Android 7.0(2016 年):采用混合編譯機制,安裝時先不編譯中間代碼,而是在用戶空閑時將能夠編譯成機器碼的那部分代碼,通過 AOT 編譯器先靜態(tài)編譯了。
如果 AOT 還沒來得及編譯或者不能編譯,再調用 JIT+ 解釋器。這種機制,相當于用時間換空間,既縮短了用戶安裝 APP 的等待時間,又將虛擬機里編譯器和解釋器能做的優(yōu)化提升到最大效率了。
Android 編譯的問題
可以看到,從 2008 年的 Android 1.0 開始,Android 在編譯優(yōu)化上面在一直下功夫。
當前的 Android 采用的是解釋執(zhí)行+JIT+AOT 的綜合模式,在空間占用+安裝速度+運行速度上已經達到了一個很好的平衡。
但是 Android 的編譯問題一直被詬病。盡管在后續(xù)的 Android 8.0 上改進了解釋器,解釋模式執(zhí)行效率大幅提升。
Android 10.0 上提供了預先放置熱點代碼的方式,應用在安裝的時候就能知道常用代碼會被提前編譯。
但是,目前來看,無論如何,Android 都沒能擺脫這樣一個前提:即應用在被打包成 APK 的時候,采用的還是 Java 代碼。
換句話說,在 APK 變成用戶可應用的過程中,還經歷了一個在 Android 系統(tǒng)內部的編譯過程,這是一個繞不過的坎。

鴻蒙實現(xiàn)跨平臺
那么,鴻蒙 OS 的代碼編譯是怎么樣的呢?他又是如何解決跨平臺的問題的呢?
從上圖中可以看到,在鴻蒙 OS 架構中,方舟編譯器和多終端開發(fā) IDE 扮演著重要的位置。
跨平臺有一個最大的挑戰(zhàn),那就是各個平臺的適配問題,尤其是目前各種設備類型越來越多,如何將同一個應用,在手機、手表、汽車、電視上面都可以適配的展示呢?
這就是多終端開發(fā) IDE 所做的事情:
使用華為提供的多終端 IDE,多語言統(tǒng)一編譯,分布式架構 Kit 提供屏幕布局控件以及交互的自動適配,支持控件拖拽,面向預覽的可視化編程。
從而使開發(fā)者可以基于同一工程高效構建多端自動運行 App,實現(xiàn)真正的一次開發(fā),多端部署,在跨設備之間實現(xiàn)共享生態(tài)。

上圖就是華為提供的 IDE,在里面可以通過圖形化界面拖拽控件,并且 IDE 可以幫助自動適配各種終端設備。
有了IDE,開發(fā)可以方便的開發(fā)一套代碼,這樣可以自動適配到各種設備中,但是各種設備所執(zhí)行的機器指令是不一樣的,如何把這一套代碼分別編譯成各個設備需要的機器指令呢?
Android 設備是由不同設備上內置的虛擬機進行編譯的,所以編譯之前就知道這個設備具體是什么了,那么,鴻蒙 OS 是怎么做的呢?這就是方舟編譯器所干的事情了。
華為方舟編譯器是首個取代 Android 虛擬機模式的靜態(tài)編譯器,可供開發(fā)者在開發(fā)環(huán)境中一次性將高級語言編譯為機器碼。
此外,方舟編譯器未來將支持多語言統(tǒng)一編譯,可大幅提高開發(fā)效率。

Android 之所以"慢",是因為他的編譯過程是在終端進行的,也就是說需要在用戶的手機上,通過虛擬機進行編譯成可執(zhí)行的機器代碼。
而鴻蒙 OS 使用的方舟編譯器,可以將高級語言(Java)直接變成機器碼,從而繞過了虛擬機。
并且這個編譯過程并不是在用戶的手機上完成的,而是在應用開發(fā)階段就完成了。

通過方舟編譯器,開發(fā)者的應用在下載之前就已經轉化成為機器可以識別的代碼,因而可以在手機上快速安裝、啟動和運行,而無需再經過 VM 的編譯。
某種程度上,方舟編譯器是將編譯過程提前到應用開發(fā)階段,從而大幅度減少了智能手機和操作系統(tǒng)的運行負擔。
華為官方介紹,方舟編譯器是首家完全替代語言虛擬機的靜態(tài)編譯器,完全不需要解釋器。并兼顧 Java 開發(fā)效率和 C 語言運行效率的編譯器。
除了代碼編譯,方舟編譯器也提供了更高效的內存機制,它與 Android 內存回收的不同之處在于:
Android 在內存回收上采用集中回收機制,發(fā)生全局回收時更需要暫停應用,這也是隨機卡頓的根因之一。
而方舟編譯器采用了引用計數(shù)法來進行內存的實時回收,并且配合使用了專門的消除環(huán)算法(消除對象互相引用帶來的無法回收問題),來避免 GC 集中式回收帶來的系統(tǒng)卡頓。
相比 GC,方舟的內存回收是實時的而非集中式的,且不需要暫停應用進程,這樣便大大消除了卡頓。
另外,就像 JVM 其實也是支持多種語言一樣,華為表示,方舟編譯器未來也會支持更多的開發(fā)語言。換句話說,其他語言的開發(fā)者,日后也能開發(fā)基于鴻蒙 OS 的應用。
參考資料:
https://www.jishuwen.com/d/2NN3
https://www.zhihu.com/question/339567108
https://www.cnbeta.com/articles/tech/876171.htm
https://www.cnbeta.com/articles/tech/876919.htm
https://juejin.im/post/5cb07000f265da037d4f9be6