我們的程式設計師對鴻蒙作業系統做了一些研究,在此和大家分享探討下。
華為鴻蒙 OS 有什麽創新,是否自主研發完全開源,本文帶你深入鴻蒙的世界。一、初識鴻蒙
國內在電腦基礎核心領域缺乏建樹,一直沒有自主知識產權的作業系統。之前又出過多起諸如 漢芯 , 紅芯瀏覽器 等造假事件,猶如現實世界的「狼來了」,使國人對任何打著自主知識產權宣傳的產品都會戴著放大鏡去看,那麽鴻蒙到底是不是個例外?
鴻蒙是個很泛的概念,鴻蒙不僅一個作業系統,還是一個生態。鴻蒙這個詞在不同的場景下指代不同的東西。根據華為官方 IDE DevEco Studio 的套用樣版可以看出,目前鴻蒙支持的器材有手機,平板,電視,手表,汽車,以及相機等小家電等等,不同的技術棧開發的套用支持的器材種類也不同。其中 Java 類別的套用支持的器材類別最為豐富,JS 類別的套用其次,C++套用支持的類別最少。
這些器材大體上可以分為嵌入式和非嵌入式兩種。根據套用所需記憶體大小又可以分為 L0-L5 六個級別:
在嵌入式領域, 鴻蒙指是一款嵌入式作業系統,鴻蒙的核心為 LiteOS,系統只能在配套的硬件(開發板)上執行,並非通用的作業系統,OpenHarmony 是其對外開源的版本,在 2020 年 9 月在 gitee 上開源 OpenHarmony 1.0,關於這款系統華為自身的文件比較欠缺,這裏有較為詳細的 開發者文件 。
在非嵌入式領域, 鴻蒙指的是一款叫鴻蒙的手機作業系統,最近網上熱議的 「此套用專為舊版鴻蒙打造」 令人疑竇叢生。
因為截至目前鴻蒙只釋出了一個版本,根本不存在所謂的舊版鴻蒙。由於鴻蒙的手機版作業系統並未開源,提示語又與 android 如此類似,不得不令人懷疑是字串批次替換。那麽事實真是字串替換如此簡單嗎?下文將會予以分析。
總的來說,鴻蒙絕不僅僅指的是作業系統,華為的野心也絕不止於此,華為是要打造一個叫鴻蒙的生態,我們不排除未來會有鴻蒙 SDK 植入其它廠商的器材,使這些器材也具備執行鴻蒙套用的能力,甚至是執行在傳統的 Windows、Linux 上的器材,那麽這些器材也可以說是一個鴻蒙器材,是鴻蒙生態的一部份。
二、鴻蒙核心
經調研,我們認為鴻蒙生態的核心是以下四點:
1、多器材相容
即開發出來的套用,可以覆蓋多種類別的器材,遮蔽底層 OS 的差異,類似目前火熱的 Flutter 所解決的問題。
2、卡片式套用
在多器材相容的基礎上帶來一致的,高效能的互動體驗。可以理解為跨器材,跨平台,跨網絡的輕量 Widget。
3、軟總線
在以上兩點的基礎上,降低器材間互聯互通的門檻。主要基於以下三點改進:
(1)器材間的發現和連線:從手動發現,前進演化成自發現:
(2)多器材互聯後的組網技術:軟總線組網-異構網絡組網:
(3)多器材多協定間的高效傳輸技術:
4、通訊安全
要實作器材間的互聯互通,那麽安全無疑是特別重要的環節。這裏的問題是如何保證正確的人使用正確的器材,消費正確的數據。即要解決如下三個問題:
(1) 如何保證消費者對器材的鑒權是安全的,保證器材是原廠生產,沒有被篡改的?(正確的器材) (2) 如何保證消費者操作器材數據是安全的? (正確的人) (3)如何保證消費者數據安全?(正確使用數據)
鴻蒙在系統和數據通訊安全方面有較為完善的考慮。
三、系統層分析
基於鴻蒙已經開源的 openharmony 源碼統計,openharmony 包含 C 程式碼 2KW 行,C++ 500W 行。
1、內核部份
鴻蒙宣傳的微內核,並未說明是哪個鴻蒙,華為目前已經釋出的內核包括: 1、Linux 面向手機 (L5 級別器材) 2、LiteOS-a 面向有 MMU 的器材 (>=L1 級別) 3、LiteOS-m 面向無 MMU 的嵌入式器材 (L0 級別)
目前行業內對內核進行分類主要是:
微內核優點: 1、程式碼量小,可以形式化驗證,可以減少 bug 量,幾乎可以 0 bug,另外更加方便移植。
2、各個系統元件或者服務如果存在問題可以直接重新開機服務,減少核心元件異常對整個系統的破壞,並按需組織系統服務。
3、各元件可以按需載入(現在整塊性核心也支持模組動態載入解除安裝)。
4、可以規避 GPL 協定。
微內核缺點:
1、所有資源獲取都需要透過 IPC,IPC 又必須陷入內核,所以會導致頻繁的陷入內核,或者多次拷貝,導致效能下降。當然 IPC 通訊效率隨著深入研究與技術發展逐步提高。
2、對於中斷響應,需要對映到使用者空間再處理,效率較低。
3、大量使用某些系統服務的時候,會導致行程上下文切換,增加系統負擔。
而目前開源出來的鴻蒙程式碼 LiteOS-a 按照業界對內核分類依舊是整塊性核心。至於華為是否存在微內核但沒有開源,還是在實作鴻蒙過程中,又重新選擇了整塊性核心,我們不得而知。
1.1 LiteOS-M
LiteOS-M 和 HW 以前開源的 Lite OS 基本相同,進行部份結構性調整,當前只適用於 cortex-m3、cortex-m4、cortex-m7、risc-v 芯片架構,是純粹的 RTOS 系統,透過 KAL 與上層服務匹配。
1.2 LiteOS-A
LiteOS-A 是 HW 基於 LiteOS 進行演進的,進行 多行程,多核,虛擬記憶體,IPC 等重新封裝,盡量類似於 Linux,但是盡量簡化內核實作。OpenHarmony LiteOS-A 內核架構圖:
LiteOS-A 是 HW 基於 LiteOS 進行演進的,進行 多行程,多核,虛擬記憶體,IPC 等重新封裝,盡量類似於 Linux,但是盡量簡化內核實作。
LiteOS-A 相對於純粹的 RTOS 增強關鍵特性簡介: 多行程: 基於 task 進行封裝,較為簡單的行程與執行緒排程(支持時間片和 FIFO 排程);
多核: 全域連結串列、所有 CPU 共享,支持空閑輪詢排程(不支持負載均衡),可支持親和設定,可繫結核執行。
虛擬記憶體 :內核靜態對映,靜態對映提升虛實轉換效率,最有區間分布(0-1 G 使用者空間,1-4 G 內核空間,減少使用者態行程頁表項),使用者態透過缺頁異常按需獲取記憶體。
動態連結: 按需載入,多套用共享程式碼段,載入最小單元為頁,符號繫結,支持立即和延時繫結,載入地址隨機化,行程程式碼段,數據段,堆疊段地址隨機化。並且執行標準 ELF 檔。
行程通訊(IPC): 支持標準的 posix 行程間通訊,如 Mqueue,pipe,fifo.signal。同時添加了 Lite IPC(類似與 Android binder 但是簡單得多),ROM 和 RAM 占用不超過 30K,達到輕量,基於白名單控制的服務存取許可權,提升安全,透過記憶體對映實作單次拷貝,實作高效。
系統呼叫: 透過 MUSL 實作系統呼叫支持 syscall API 和 VDSO API。VDSO 是減少系統呼叫開銷的方式,Linux 也支持。保證服務與內核分離。並且服務和套用不能隨意存取內核。
許可權管理: 行程粒度的許可權劃分與管理,完成 DAC 存取控制,以行程 UID 的配置,靈活劃分檔資源歸屬與管控,提供 UGO(user,group,other)的許可權分配,滿足基本的檔共享需求和 Posix 規範。
虛擬檔案系統: VFS 管理根目錄,掛載點內目錄有 FS 管理。透過 BCache 和 PCache 提升檔案系統讀寫速度。
POSIX 標準庫: 基於 Musl C 的 posix 標準庫,當前支持 1000+的標準 Posix 介面。使用者態使用全量 Musl,C++使用 libC++,內核使用部份 Musl。
以上特性都基本上基於 Linux 的簡化版本,保持內核小型化,並且盡量擁有 Linux 的功能特性。
1.3 Linux
鴻蒙 OS Linux 內核基於 Linux 4.19 版本內核,添加如下功能。
修補程式所涉及的 CVE(Common Vulnerabilities and Exposures)安全漏洞是透過 NVD (https:// nvd.nist.gov/ )官方機構收集,且修補程式已經進入 LTS 4.19.y 分支或主線,主要涉及儲存(btrfs/scsi/)、網絡(net/bpf/mwifiex) 、驅動(xen/nfc),對應 CVE 列表參考 commit 資訊中 CVE 欄位資訊。
HDF 驅動、binder ipc 轉發功能等特性支持。
vendor 廠商提供的特定芯片架構驅動程式碼:
hisi_linux-4.19_hos_l2.patch: 在 Hi3516DV300 芯片上支持 arm 架構的內核啟動(DTS 等)及對應的 drm/mmc 等驅動的支持。
2、子系統
openharmony LiteOS-A 包含如下子系統:
根據不同器材形態的部署環境,基礎軟件服務子系統集、增強軟件服務子系統集、硬件服務子系統集內部可以按子系統粒度裁剪,每個子系統內部又可以按功能粒度裁剪。
3、多內核支持
如上圖所示,對於鴻蒙 OS,其可以支持各種內核(目前支持 Liteos-m,LiteOS-a,Linux)。其透過 KAL 層對上層提供統一的 API 介面能力。
我們可以清楚的看到 KAL 支持統一是透過支持 POSIX 和 CMSIS(針對 arm Cotex-m 的抽象,做到在 RTOS 層面的盡量統一)對底層內核進行統一封裝。做到基於上層 API 的程式可以在相應的 CPU 下編譯通用,強調只能 編譯通用 。
其中相容 POSIX 的庫是 Musl-libc。該庫是一個輕量級的 C 標準庫,設計作為 GNU C library (glibc)、 uClibc 或 Android Bionic 的替代用於嵌入式作業系統和流動通訊器材。它遵循 POSIX 2008 規格和 C99 標準,采用 MIT 特許證授權,使用 Musl 的 Linux 發行版和專案包括 sabotage,bootstrap-linux,LightCube OS 等等,然後透過 HDF 來統一驅動模組的編寫偵錯過程。以此來相容驅動器材。
POSIX 表示可移植作業系統介面(Portable Operating System Interface of UNIX,縮寫為 POSIX ),POSIX 標準定義了作業系統應該為應用程式提供的介面標準。POSIX 標準意在期望獲得原始碼級別的軟件可移植性。換句話說,為一個 POSIX 相容的作業系統編寫的程式,應該可以在任何其它的 POSIX 作業系統(即使是來自另一個廠商)上編譯執行。
CMSIS(Cortex Microcontroller Software Interface Standard)標準,它是 ARM 同各個微控制器供應商、工具供應商和軟件解決方案一起開發的 Cortex 微控制器軟件介面標準。它使得微控制器和軟件供應商可以使用一致的軟件結構來開發 Cortex 微控制器的軟件。
CMSIS-RTOS 是 CMSIS 的一部份,它本身是一種 API 規範,各廠商可以基於 CMSIS-RTOS 構建自己的即時作業系統(RTOS)。由於基於 CMSIS-RTOS 的 API 是標準化的,所以基於這些 API 開發的套用軟件,不需要進行額外的移植開發工作,就可跑在任何支持 CMSIS-RTOS 的 OS 上。隨著基於 CMSIS-RTOS 的中介軟體越來越多,支持 CMSIS-RTOS 後的 OS 也會因此獲得更多的中介軟體。
4、HDF 驅動架構
OpenHarmony 驅動主要部署在內核態,當前主要采用靜態連結方式,隨內核子系統編譯和系統映像打包。
驅動框架互動流程
如上圖所示,釋出器材服務,即在 VFS 建立固定的目錄或者器材節點,並且透過 HDI 進行抽象。
下列是相關系統的適配層,讓相應的內核支持 HDF 能力。然後驅動開發工程師透過 drivers_framework 提供的相關框架能力,編寫 HDF 支持的各種驅動,所以 HDF 統一驅動,是建立在對各種內核整合的 HDF 內核支持驅動作為轉換層。 所以如果有新的內核需要適配,那麽 khdf 需要根據相應的內核,進行移植,具有較大工作量。
相關源碼目錄是:
下圖是 HDF-Framework 層。用於支持 HDF 統一驅動的開發,載入生效或者解除安裝。
透過程式碼中的 uhdf/uhdf2 可以看到,鴻蒙 OS 也在嘗試將部份驅動放入使用者空間,也就是向微內核(或者混合內核)方向演進。但如果是使用 Linux 內核,通常也可以使用標準的 Linux 內核驅動模型編寫驅動。只是不方便移植到其他的鴻蒙非 Linux 內核的器材。不過不同的器材,其 CPU 與外設可能並不相同,分別編寫也可能。
四、軟總線分析
鴻蒙提供的標準軟件總線框架圖:
主要程式碼目錄如下圖,lite 和 standard 有一定差異。針對 lite 器材,只有發現,認證傳輸。
針對標準系統,則添加了組網,並且以 client(SDK 目錄)+Server(core 目錄)的方式設計。
現在開源出來的 openharmony 方案總體約束為在同一區域網路下進行軟總線互通。目前開源出來的還是 TCP/IP 協定建立的區域網路。鴻蒙釋出會描述的極簡協定統一層,我們並沒有看到。
軟總線的時序圖如下,Module 可以看成分布式排程服務等,即其他使用軟總線的模組。
對於 pubulicService 對服務進行釋出,實際同時對 軟總線進行初始化。(前提是 WiFi 已經接入了 WiFi 的區域網路)
傳輸在上面的 publicService 過程中建立的會話服務 CreateSessionServer()就是後續進行基於 session 會話服務的基礎。 呼叫者並不需要關心 IP 等,只需要使用建立的 sessionID 進行通訊即可。
相關的程式碼:
在 StartBus()函數會呼叫 StartSession()函數建立基於 TCP 的 socket 的會話管理服務。
迴圈監聽服務來連線,數據傳輸。
簡單總結,就是軟總線的傳輸,是基於 COAP 釋出服務,等待超級終端透過 softbus 的 session 進行傳輸。當 client 要存取某個器材(可以是遠端,可以是本地)的服務,首行連線遠端服務的 session 伺服器,並行送數據。遠端的 session 服務透過 onBytesRecived 接收到數據,並回呼給 module。而是用 module 的目的。發送數據呼叫 SendBytes,就可以基於 sessionID 發送。
這個過程中,module 也好,還是遠端 client 的套用也好,都不需要知道服務在哪個地方,有軟件總線進行處理即可,目前服務的釋出只支持 WiFi 下的 COAP。
在程式碼中可以看到,未來支持的軟總線器材有 BLE,COAP,USB 三種類別。
我們推測軟件總線之下應該還有一個針對復雜器材支持多層連線的適配層,以便遮蔽底層差異(當前只開源了 WiFi 和 BT),包括支持上述器材的組網,路由以便構建一張區域網路。根據當前的開原始碼來看,主要還是基於 wifi 的區域網路連線,其他形式自組網還未看到,但華為在通訊這塊有很深的功底,我們這裏相信這個目標可以達成。
基於目前公開的資訊,軟總線架構推測如下圖:
其中底層連線協定包括乙太網路、紅外線、4G/5G/WiFi、BT、NFC 等各種通訊能力。目前 NFC 主要用於華為 Card 的認證,協助多器材之間的認證。
五、套用層分析
我們分別編寫了鴻蒙的 JS 及 Java 套用,結合開放出來的部份源碼及文件,對 App 安裝包進行了簡單的逆向分析。
1、開發環境
官方 IDE DevEco Studio 是基於開源的 intellij 的改造,能夠用於本地偵錯的模擬器只支持 JS 套用。Java 套用截止目前只支持遠端模擬器(所謂分布式模擬器)不支持本地模擬器。執行遠端模擬器都需要賬號密碼登入,賬號密碼需要註冊華為 ID 並實名認證,而實名認證需要上傳身份證照片或者銀行卡資料,遠端偵錯由於網絡和資源分配原因並不流暢,流暢度和畫質方面不盡人意,開發體驗有點兒糟糕。
當然如果有真機,也可以使用真機進行開發偵錯,但華為這裏又設了兩道門檻,開發鴻蒙套用需要雙重簽名認證,除了套用本身的簽名,還要對套用工程進行簽名。這兩個簽名都需要在鴻蒙開發者網站上註冊,生成相應證書後方可安裝到真機,步驟相當繁瑣。筆者搞這個簽名走各種註冊流程前後耗時一小時,對開發者不是很友好,好在配置完成後,後續可以直接使用,算是一次性勞動。
從目前的套用開發流程上看,以後開發鴻蒙套用有可能會對簽名服務進行收費,筆者不禁回想起了諾基亞,摩托羅拉時代,J2ME 套用證書簽名外包給第三方公司,一個套用簽名收費 2000 元否則無法安裝到使用者手機,搞死生態的事情。生態還沒起來,套用開發流程搞的如此復雜,希望華為借鑒這個歷史教訓。
2、套用框架
鴻蒙套用 UI 框架有兩套,支持 Java、JS,IDE 裏有預設的樣版。這兩套框架的區別是,Java 框架只支持鴻蒙 Android 系統,JS 套用既支持鴻蒙 Android 系統,也支持鴻蒙嵌入式系統。鴻蒙 JS 套用在鴻蒙 Android 上是套了個 Android 套用的殼,這個殼會構建一個類似小程式的渲染環境,轉換為 Android 的原生控制項渲染,下文有展開分析。JS 套用相比 Java 套用,在排版能力,擴充套件性,相容性方面存在一定的局限性,更適合做資訊展示類的套用。
對應的也有,Java 和 JS 兩套 SDK,鴻蒙系統提供的名為 Ability 的套用框架也分別有 Java 和 JS 的實作。套用支持哪些器材,可以在套用的 config.json 中聲明。
3、套用格式
無論是 js 套用還是 java 套用,程式碼最終編譯出來包均為 hap 字尾,這個 hap 是未經 hack 的 zip 格式,可以使用標準的 zip 解壓工具進行解壓。
具體 hap 包的具體安裝使用上,SDK 提供命令列工具 hdc:
hdc shell am force-stop com.example.myapplication
hdc shell bm uninstall com.example.myapplication
hdc file send ~/DevEcoStudioProjects/MyApplication/entry/build/outputs/hap/debug/entry-debug-unsigned.hap /sdcard/entry-debug-unsigned.hap
hdc shell bm install -p /sdcard/
hdc shell rm -rf /sdcard/xxx
hdc shell am start -n "com.example.myapplication/com.example.myapplication.MainAbilityShellActivity" -D
hdc app install xxx.hap
3.1、Java 套用
java 套用在開發時依賴以下 SDK 包,只能用來編譯程式碼,SDK 反編譯看不到源碼,也未開源。
根據檔命名,對其功能推測如下:
檔名 | 描述 |
---|
Java 套用解壓後的產物如下:
這些檔的作用如下:
Java 套用起來後用 MainAbilityShellActivity 承載,根據反編譯後的殼代碼分析,主要由 HarmonyApplication 完成對 ability 套用執行環境的初始化。
Java 套用布局檔及顯示效果如下圖:
dump 出 UI 的繪制方式(adb shell uiautomator dump),可以看到鴻蒙雖然定義了一套套用開發的 DSL,但繪制部份還是用 Android 的 UI 控制項來承載,非自繪 UI。
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][1176,2328]">
<node index="0" text="" resource-id="android:id/decor_content_parent" class="android.view.ViewGroup" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][1176,2328]">
<node index="0" text="" resource-id="android:id/action_bar_container" class="android.widget.FrameLayout" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,72][1176,240]">
<node index="0" text="" resource-id="android:id/action_bar" class="android.view.ViewGroup" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,72][1176,240]">
<node index="0" text="entry_MainAbility" resource-id="" class="android.widget.TextView" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[48,115][528,196]" /></node>
</node>
<node index="1" text="" resource-id="android:id/content" class="android.widget.FrameLayout" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,240][1176,2328]">
<node index="0" text="" resource-id="" class="android.view.ViewGroup" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,240][1176,2328]">
<node index="0" text="你好,世界" resource-id="" class="android.widget.TextView" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[288,1160][888,1320]" />
<node index="1" text="javaApp" resource-id="" class="android.widget.TextView" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[366,1320][809,1480]" /></node>
</node>
</node>
<node index="1" text="" resource-id="android:id/statusBarBackground" class="android.view.View" package="com.michalliu.myapplication" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][1176,72]" /></node>
</hierarchy>
由此可以看出,鴻蒙 Android 版要脫離 Android 體系難度還比較高,畢竟核心的 UI 部份非自繪。
Java 套用的執行環境示意圖:
我們理解鴻蒙 Android 從設計上更類似 QT 跟 Windows 的關系,可以理解為在 Android 作業系統的基礎上搭了一套自己的應用程式框架。
目前鴻蒙是跟 Android 深度繫結的,鴻蒙切換作業系統的可能性不是完全沒有,但成本相當高,應該說鴻蒙 Android 的這個設計思路是既然擺脫不了安卓,基於這個前提,那麽就充分利用它。
3.2、Js 套用
從目前已經開源出來的部份上來看基於 js 開發的套用是一種類似小程式的開發方式,html,js,css 首先會編譯成 jsbundle(編譯工具本身未開源),jsbundle 的執行不同的鴻蒙系統上有所區別。
經過對 openharmony 代碼分析,在 openharmony 裏 Js 套用是以自繪的方式渲染,支持的 UI 元件看起來還比較完善(從源碼裏看繪制部份似乎參考了部份 flutter 程式碼),使用三星的 Jerry Js 引擎,猜測是挖的三星的人?因為這個 Js 引擎實在太小眾,Google V8 他不香嗎?
UI 元件框架在 ace_engine_lite 裏,從開源的程式碼我們看出支持的 UI 元件還比較豐富,除了常規的控制項,還包含列表,動畫等復雜控制項的實作。
ace_engine_lite 負責維護 UI 元件的生命周期,事件通訊,數據更新等,是邏輯層
UI 元件的顯示層在 graphic_ui 工程中,例如下圖為 UIButton 繪制的實作:
目前這個自繪的工程只有嵌入式的的實作,沒有 Android 對應的實作。
實際在 Android 工程上,鴻蒙走的並不是自繪的方案,而是類似 ReactNative 的控制項轉換,ReactNative 采用的是 React 的語法,而鴻蒙 Android 采用的是 Vue 的語法,從國內的開發者生態上來看,這是個正確的選擇。
鴻蒙的這個用 C++實作類 VUE 語法,在嵌入式上自繪,Android 上控制項轉換的 Js 跨平台渲染框架屬於原創,可惜的是鴻蒙 Android 這塊並未開源,不能深入研究。
Js 套用在鴻蒙 Android 上會轉換成 Android 的 UI 控制項,Js 套用解壓後的產物如下:
這些檔的作用如下:
檔 | 描述 |
---|
對於 Js 套用來說核心邏輯由 ohos.aafwk.ace.ability.AceAbility 完成 jsbundle 的載入和執行工作。
(註意:雖然 java 套用和 js 套用在解壓後目錄結構似乎差不多,檔命名也差不多,但其工作原理完全不同。在 Java 套用裏 class.dex 已經是鴻蒙套用的真正可執行程式碼。在 js 套用裏 class.dex 還是一個殼,這個殼用於打造執行 Js 套用的執行環境,真正的業務邏輯在 app.js 裏。)
js 套用布局檔及顯示效果:
dump 出 UI 的繪制方式,可以看到 Js 套用的 UI 繪制,在鴻蒙 Android 上是用 Android 的 UI 控制項來承載,非自繪 UI。
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<hierarchy rotation="0">
<node index="0" text="" resource-id="" class="android.widget.FrameLayout" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][1176,2328]">
<node index="0" text="" resource-id="android:id/decor_content_parent" class="android.view.ViewGroup" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,0][1176,2328]">
<node index="0" text="" resource-id="android:id/action_bar_container" class="android.widget.FrameLayout" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,72][1176,240]">
<node index="0" text="" resource-id="android:id/action_bar" class="android.view.ViewGroup" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,72][1176,240]">
<node index="0" text="entry_MainAbility" resource-id="" class="android.widget.TextView" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[48,115][528,196]" /></node>
</node>
<node index="1" text="" resource-id="android:id/content" class="android.widget.FrameLayout" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[0,240][1176,2328]">
<node index="0" text="" resource-id="" class="android.view.ViewGroup" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="true" enabled="true" focusable="true" focused="false" scrollable="true" long-clickable="true" password="false" selected="false" bounds="[0,240][1176,2328]">
<node index="0" text="您好 世界" resource-id="" class="android.widget.TextView" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="true" enabled="true" focusable="true" focused="false" scrollable="true" long-clickable="true" password="false" selected="false" bounds="[331,1173][844,1332]" />
<node index="1" text="Js Application" resource-id="" class="android.widget.TextView" package="com.example.myapplicationjs" content-desc="" checkable="false" checked="false" clickable="true" enabled="true" focusable="true" focused="false" scrollable="true" long-clickable="true" password="false" selected="false" bounds="[301,1347][874,1452]" /></node>
</node>
</node>
</node>
</hierarchy>
鴻蒙套用層在設計上,基於自己的 DSL 和套用執行框架,在嵌入式器材上以自繪的方式渲染,在鴻蒙 Android 上透過適配層轉換為 Android 原生控制項渲染。這樣的設計優勢是減輕了工作量,元件方面可以復用 Android 的生態,能力會更豐富,畢竟從零再打造一套完整且龐大的 UI 體系成本太高,體驗還不一定有 Android 做的好,而劣勢則是犧牲了可維護性,兩套方案要各自獨立維護,維護成本較高,另外還可能帶來相容性的問題。從 openharmony 源碼上看,基於自繪方案並沒有預留給 Android 的擴充套件介面,targetos 僅包含 linux 和 liteos 兩種,因為渲染層架構不同,未來的改成一致的可能性也較低。
六、總結
鴻蒙 OS 並不定位於對 Windows、Android 進行替代,而是劍指萬物互聯時代全場景、多終端的作業系統,與此相對應,鴻蒙 OS(及大華為體系)所有的生態布局也將圍繞萬物互聯展開。鴻蒙 OS 在完成細分場景的拓展與跑馬圈地後,鴻蒙 OS 將完善華為 AIoT 生態,進一步在智慧城市、車聯網(深化)、工業互聯網三方面發力推進。
中長期來看,鴻蒙 OS 與華為「雲+端」芯片形成強大合力,進軍產業物聯網。華為優質網絡器材是 IoT 的連線基礎,連線獲得了大量數據,但只有透過智能分析才能夠形成殺手級套用。華為已在雲側和端測擁有昇騰、鯤鵬、麒麟等芯片,具備強大算力,疊加鴻蒙 OS 高效、靈活的執行力,將培育大量高價值套用。基於近景和遠景的生態藍圖,當前鴻蒙 OS 的發力抓手仍是以移動端為核心的 HMS 產業鏈。