HarmonyOS 應(yīng)用開發(fā)剖析

1. 前言


??HarmonyOS 2.0發(fā)布已經(jīng)有一段時(shí)間了,周邊也有一些小伙伴的華為手機(jī)升級(jí)了,因此本文就來談一談HarmonyOS 應(yīng)用開發(fā)相關(guān)的一些內(nèi)容。

??首先說下這里說的HarmonyOS,并非OpenHarmony,以目前官方開源的代碼來看,這兩者不是一回事,通過對(duì)OpenHarmony官方開源的代碼分析,當(dāng)前華為手機(jī)上運(yùn)行的HarmonyOS 2.0系統(tǒng)并不是基于OpenHarmony來開發(fā)的,并且OpenHarmony當(dāng)前開放的源碼中也沒有找到任何Java虛擬機(jī)相關(guān)代碼,沒有Java虛擬機(jī)怎么能運(yùn)行Java應(yīng)用呢。

??通過從HarmonyOS 2.0的手機(jī)設(shè)備上導(dǎo)出framework包反編譯分析,目前能確定的是HarmonyOS 2.0是基于AOSP(Android Open Source Project 安卓開源項(xiàng)目)開發(fā)的,不過鴻蒙在framework層增加了很多特性,比如支撐hap文件(鴻蒙應(yīng)用打包后的格式)的啟動(dòng)和運(yùn)行,支持js UI以及鴻蒙系統(tǒng)最核心的分布式框架(包含分布式軟件總線、虛擬設(shè)備等內(nèi)容)等。

??因此本文的內(nèi)容主要聚焦在華為手機(jī)上運(yùn)行的HarmonyOS 2.0系統(tǒng)的應(yīng)用開發(fā)。

2. 應(yīng)用開發(fā)框架


??HarmonyOS(后文簡(jiǎn)稱鴻蒙)提供的sdk包含了全面的API供開發(fā)者使用,開發(fā)鴻蒙應(yīng)用過程中不會(huì)用到原生Android sdk,也沒有四大組件、AndroidManifest.xml等相關(guān)內(nèi)容。使用的IDE也是基于IDEA開發(fā)的,和AndroidStudio基本類似。鴻蒙sdk主要API框架可以看下圖,后面會(huì)針對(duì)幾個(gè)特性展開介紹。

應(yīng)用開發(fā)框架

2.1. Ability框架

??Ability框架是開發(fā)者接觸最密切的API,表示應(yīng)用所具備的能力。Ability可以分為FA(Feature Ability)和PA(Particle Ability)兩種類型,是應(yīng)用的基本組成單元。FA提供與用戶交互的能力,PA提供后臺(tái)服務(wù)和數(shù)據(jù)訪問能力。一個(gè)應(yīng)用可包含一個(gè)或多個(gè)FA和PA,具體如下圖所示。

Ability結(jié)構(gòu)

??FA和PA作為分發(fā)平臺(tái)分發(fā)的最小單位,支持同一個(gè)應(yīng)用在不同的平臺(tái)下發(fā)不同的FA或PA,比如視頻通話應(yīng)用在手機(jī)設(shè)備下發(fā)一個(gè)FA和三個(gè)PA,但是在智慧屏設(shè)備只下發(fā)一個(gè)FA和一個(gè)PA,如下圖所示。

FA/PA分發(fā)框圖

??下面我們來看一下FA/PA和原生Android系統(tǒng)的關(guān)系。其實(shí)Ability框架的幾個(gè)重要部分都需要依賴AOSP的四大組件來支撐,這對(duì)Android開發(fā)者來說再熟悉不過了,具體看下圖。

Ability與AOSP對(duì)應(yīng)關(guān)系

??這個(gè)依賴關(guān)系是怎么建立的呢?由于在鴻蒙應(yīng)用開發(fā)過程中,對(duì)AOSP的任何特性和接口都是透明的,沒辦法直接使用Android原生的四大組件,因此這個(gè)依賴過程發(fā)生在編譯期,鴻蒙開發(fā)插件會(huì)在編譯過程生成對(duì)應(yīng)Android四大組件相關(guān)的一些模板代碼(為什么稱為模板代碼,后面會(huì)再次提到),這些模板代碼會(huì)通過一個(gè)配置文件(config.json)來獲取Ability相關(guān)的界面(FA)和服務(wù)(PA),然后產(chǎn)生關(guān)聯(lián)。

??這里的FA也有類似Activity的生命周期,具體咱們還是來看下圖。

FA生命周期

2.2. UI框架

??鴻蒙應(yīng)用的UI框架支持兩種開發(fā)語言:Java和JS,Java UI框架使用鴻蒙AGP框架,AGP框架并不使用Android原生的任何現(xiàn)成的UI控件,其內(nèi)部主要是基于SurfaceView重新自定義了一套UI控件;JS UI框架主要依賴于ACE框架,一套跨平臺(tái)的UI框架,那么這個(gè)跨平臺(tái)要跨到哪里呢?就是前面提到的OpenHarmony,其內(nèi)部也有ACE框架。如果一個(gè)鴻蒙應(yīng)用是通過純JS編寫的,那么理論上是可以快速遷移到OpenHarmony平臺(tái)。鴻蒙應(yīng)用開發(fā)工具同時(shí)支持兩種平臺(tái)的App開發(fā),但是要切換SDK。

UI框架

2.3. 服務(wù)卡片

??服務(wù)卡片是FA的一種界面展示形式,將FA的重要信息或操作展示到卡片上,目的是服務(wù)直達(dá)和減少體驗(yàn)層級(jí)。服務(wù)卡片也是鴻蒙官方最近一直在推的一種。其實(shí)跟原生Android的桌面掛件類似。但是也有不一樣的地方,服務(wù)卡片有單獨(dú)的入口,讓用戶可以更快到達(dá)。并且提供了更方便的接入方式——原子化服務(wù)。

服務(wù)卡片

2.4. 原子化服務(wù)

??服子化服務(wù),實(shí)際是一種輕量級(jí)的應(yīng)用(免安裝)。類似于Google的instant APP。主要是想提供一種新的服務(wù)體驗(yàn),讓應(yīng)用開發(fā)更簡(jiǎn)單、服務(wù)的獲取和使用更便捷,有單獨(dú)的入口。相比傳統(tǒng)應(yīng)用,原子化服務(wù)具備如下一些特點(diǎn)。

特點(diǎn) 原子化服務(wù) 傳統(tǒng)應(yīng)用
分發(fā)平臺(tái) 原子化服務(wù)平臺(tái) 應(yīng)用商店
桌面icon 無桌面icon,但可手動(dòng)添加到桌面,顯示形式為服務(wù)卡片 有桌面icon
安裝要求 免安裝(包體不超過10MB) 需要安裝

2.5. 流轉(zhuǎn) - 多設(shè)備分布式操作

??流轉(zhuǎn)是鴻蒙平臺(tái)分布式能力的一個(gè)很重要的體現(xiàn),其實(shí)現(xiàn)原理就是鴻蒙的分布式框架。
??流轉(zhuǎn)主要有兩種,跨端遷移多端協(xié)同

??跨端遷移:指在A端運(yùn)行的FA遷移到B端上,完成遷移后, B端FA繼續(xù)任務(wù),而A端應(yīng)用退出。
??比如一個(gè)同事下班后乘坐地鐵回家,在地鐵上用手機(jī)觀看一部電影,但是電影還沒看完,他已經(jīng)回到家里,回家后打開電視就能繼續(xù)看。

??多端協(xié)同:多端上的不同或相同F(xiàn)A/PA同時(shí)運(yùn)行,或交替運(yùn)行實(shí)現(xiàn)完整的業(yè)務(wù)。
??比如現(xiàn)在很多學(xué)生都要上網(wǎng)課,它可以將平板側(cè)應(yīng)用A做答題板,智慧屏側(cè)應(yīng)用B做直播。不同的端共用完成同一個(gè)任務(wù)。

流轉(zhuǎn)框架

??鴻蒙系統(tǒng)內(nèi)置了分布式框架,應(yīng)用只需要通過其sdk提供的API去開發(fā)即可快速地支持這種分布式特性,不過這種流轉(zhuǎn)當(dāng)前僅支持多端登錄同一個(gè)華為賬號(hào) + 局域網(wǎng)內(nèi)。

??除了以上介紹的這些,還有很多鴻蒙平臺(tái)特有的能力,比如卡片分享、分布式文件服務(wù)、分布式數(shù)據(jù)服務(wù)和AI接口,總體而言鴻蒙對(duì)分布式的支持是比較全面的,這也體現(xiàn)了全場(chǎng)景超級(jí)終端的概念。

3. 發(fā)布包文件解析


3.1. 項(xiàng)目結(jié)構(gòu)和發(fā)布包格式

??鴻蒙應(yīng)用項(xiàng)目的結(jié)構(gòu)和發(fā)布包形態(tài)如下圖所示,一個(gè)鴻蒙應(yīng)用主要包含兩種模塊:
?? Entry模塊:應(yīng)用的入口模塊。一個(gè)應(yīng)用項(xiàng)目中有且只有一個(gè)entry模塊。
?? Feature模塊:應(yīng)用的動(dòng)態(tài)特性模塊。一個(gè)應(yīng)用項(xiàng)目可以包含零個(gè)或多個(gè)feature模塊。

??鴻蒙的應(yīng)用架構(gòu)默認(rèn)實(shí)現(xiàn)了類似Android上的組件化架構(gòu),每個(gè)模塊支持獨(dú)立編譯、打包、安裝和調(diào)試。對(duì)于大型應(yīng)用可以有效提升開發(fā)效率。

??鴻蒙應(yīng)用發(fā)布包是APP包(.app后綴),內(nèi)部由一個(gè)或多個(gè)HAP(HarmonyOS Ability Package)包組成。每個(gè)模塊編譯后對(duì)應(yīng)生成一個(gè)hap文件。

應(yīng)用項(xiàng)目結(jié)構(gòu)和發(fā)布包格式

3.2. HAP文件結(jié)構(gòu)

??每個(gè)hap文件就對(duì)應(yīng)項(xiàng)目中的一個(gè)模塊,這里我們具體看下hap的文件結(jié)構(gòu)。HAP是Ability的部署包,每個(gè)hap文件支持單獨(dú)安裝和調(diào)試,hap文件的內(nèi)部結(jié)構(gòu)如下圖所示,下面我們逐一介紹。

HAP文件結(jié)構(gòu)

??apk文件:這個(gè)apk文件的內(nèi)容跟一個(gè)常規(guī)apk文件沒什么區(qū)別。包含AndroidManifest.xml、res、resources.arsc和classes.dex。這里的classes.dex文件內(nèi)部包含了應(yīng)用打包過程自動(dòng)產(chǎn)生的模板代碼。這個(gè)模板代碼就是讓Android原生四大組件和Ability產(chǎn)生關(guān)聯(lián)的關(guān)鍵。
??config.json:配置文件,它的作用相當(dāng)于原生Android應(yīng)用的Androidmanifest.xml,F(xiàn)A/PA和權(quán)限申請(qǐng)等都需要在該文件里面配置。
??assets目錄:包含了Java代碼用到的資源文件以及js代碼。
??libs目錄:包含依賴庫,與常規(guī)apk文件內(nèi)部的libs類似。
??pack.info:一些打包信息。
??classes.dex:apk外部的classes.dex,開發(fā)者寫的業(yè)務(wù)代碼。

??為什么這里要把Java代碼拆分到兩個(gè)地方,一個(gè)在apk內(nèi)一個(gè)在apk外呢?猜測(cè)可能是基于兩方面的考慮,一方面是這兩份代碼的含義不一樣,apk內(nèi)部的是編譯過程產(chǎn)生的模板代碼,apk外部是開發(fā)者寫的業(yè)務(wù)代碼。一方面是層次不一樣,apk內(nèi)部的代碼是在原生Android 應(yīng)用運(yùn)行框架用到,apk外部的是鴻蒙應(yīng)用運(yùn)行框架加載的。

3.3. 應(yīng)用安裝

??通過上面內(nèi)容我們知道,一個(gè)鴻蒙APP文件是多個(gè)HAP文件的壓縮包,那么它會(huì)如何被安裝到手機(jī)上呢。鴻蒙應(yīng)用安裝時(shí)系統(tǒng)會(huì)從每個(gè)hap文件中提取出apk文件,entry.hap內(nèi)部的apk文件會(huì)被重命名為base.apk(作為應(yīng)用的入口),其它hap內(nèi)部的apk會(huì)被重命名為split_featureName.apk,安裝后的目錄結(jié)構(gòu)如下所示。

/data/app/package.name-xxx==/base.apk
/data/app/package.name-xxx==/split_featureName.apk
/data/app/package.name-xxx==/feature_entry-debug-rich-signed.hap
/data/app/package.name-xxx==/feature_featureName-entry-debug-rich-signed.hap

??這個(gè)安裝過程看起來像AAB(Android App Bundle)。但有個(gè)地方不太一樣,原生的split APKs機(jī)制在安裝aab包時(shí)會(huì)合并每個(gè)apk內(nèi)部的AndroidManifest.xml文件到base.apk文件里面,但鴻蒙這里的feature.apk的AndroidManifest.xml內(nèi)容沒有被合并到base.apk內(nèi)部。

4. 應(yīng)用啟動(dòng)和運(yùn)行


4.1. HAP啟動(dòng)流程

??對(duì)于AOSP而言,啟動(dòng)一個(gè)應(yīng)用必然需要apk文件。前文提到的hap文件里面包含的apk文件就是啟動(dòng)一個(gè)鴻蒙應(yīng)用的入口(安裝后就是base.apk)。該apk內(nèi)部包含一個(gè)ShellMyApplication類,該類就是鴻蒙應(yīng)用啟動(dòng)的入口代碼。ShellMyApplication的代碼如下所示:

import ohos.abilityshell.HarmonyApplication;

public class ShellMyApplication extends HarmonyApplication {
    @Override
    public void onCreate() {
        super.onCreate();
    }
}

??這個(gè)代碼就是我們前面提到的鴻蒙應(yīng)用在編譯過程中產(chǎn)生的模板代碼,主要作用是作為一層代理將邏輯轉(zhuǎn)移到鴻蒙的運(yùn)行框架。這個(gè)HarmonyApplication繼承了原生Android的Application,并且在AndroidManifest.xml里面注冊(cè)。所以當(dāng)Android原生系統(tǒng)啟動(dòng)一個(gè)App的時(shí)候,首先就會(huì)加載這個(gè)Application。啟動(dòng)的大概流程如下圖所示。

HAP啟動(dòng)流程

??在Application的attach階段,會(huì)去加載鴻蒙應(yīng)用運(yùn)行框架,解析config.json并全局緩存,因?yàn)樵撆渲眯畔⒄麄€(gè)應(yīng)用生命周期都會(huì)使用,然后再去配置類加載器和底層庫的路徑(包括所有apk文件和hap文件),這樣才能確保其它apk文件和hap文件里面的類和so文件能被正常加載。在onCreate階段會(huì)進(jìn)行DataAbility的初始化,這跟原生Android的Provider的初始化時(shí)機(jī)是類似的。

4.2. HAP運(yùn)行框架

??這里以一個(gè)有界面的DemoAbility為例來看一下鴻蒙的應(yīng)用運(yùn)行框架,如下圖所示。其它的Ability的流程都是類似的。

??這里我們分成了四個(gè)層次,上面兩層可以認(rèn)為是原生Android APK的運(yùn)行框架。下面兩層是鴻蒙應(yīng)用的運(yùn)行框架。

??當(dāng)啟動(dòng)一個(gè)界面時(shí),原生Android會(huì)加載一個(gè)Activity文件(DemoAbilityShellActivity,也是模板代碼),DemoAbilityShellActivity只是簡(jiǎn)單的實(shí)現(xiàn)了AbilityShellActivity,而AbilityShellActivity也只是簡(jiǎn)單實(shí)現(xiàn)了Activity基類,然后把所有方法轉(zhuǎn)移到Activity的代理層,這個(gè)代理層已經(jīng)脫離了Activity,后續(xù)就正式進(jìn)入了鴻蒙應(yīng)用運(yùn)行框架,然后再層層回調(diào)到AOSP的View框架,

??通過這個(gè)流程我們大概知道,鴻蒙Framework在這邊除了自己實(shí)現(xiàn)了一套UI框架之外,主要承擔(dān)的就是代理作用。如果以后HarmonyOS拿掉AOSP后,鴻蒙應(yīng)用項(xiàng)目是不是只需要切換一下鴻蒙sdk即可適配新系統(tǒng)呢?

HAP運(yùn)行框架

5. Android項(xiàng)目適配


??通過上文我們大致了解了鴻蒙應(yīng)用開發(fā)知識(shí),現(xiàn)在有一個(gè)很現(xiàn)實(shí)的問題,對(duì)于原Android項(xiàng)目,我們要如何使用鴻蒙平臺(tái)的這些特殊能力呢。鴻蒙致力于打造一套全新的開發(fā)框架,但如果想將現(xiàn)有Android老項(xiàng)目遷移到鴻蒙,就需要重新開發(fā),其成本不言而喻。 以目前來看鴻蒙與AOSP有著千絲萬縷的聯(lián)系,因此是不是有一種折中的方案,直接基于現(xiàn)有的Android項(xiàng)目去適配鴻蒙,去使用鴻蒙的平臺(tái)特性呢。

??當(dāng)前網(wǎng)上流傳一種混合打包的解決方案能解決這個(gè)問題,這里簡(jiǎn)要介紹下該方案。核心就是將entry模塊模板apk文件替換成現(xiàn)在有Android項(xiàng)目編譯出來的apk文件,由于entry模塊的apk是整個(gè)應(yīng)用的入口,當(dāng)該apk被替換成原Android項(xiàng)目打包出來的apk文件后,當(dāng)該應(yīng)用啟動(dòng)時(shí)就會(huì)直接加載Android apk文件。而Android apk與其它Hap模塊的調(diào)用方式可以通過反射或四大組件。替換后的APP包結(jié)構(gòu)如下。

混合打包方案

??雖然該方案有成功上線的案例,但也存在一些不足:
??未來不確定性:一種官方支持但沒有公開的臨時(shí)方案。
??打包步驟繁瑣:需要兩次打包,先打包出apk文件再打包鴻蒙應(yīng)用。
??代碼交互能力弱:安卓應(yīng)用和鴻蒙應(yīng)用的代碼是不可見的,主要通過Android四大組件和反射進(jìn)行互調(diào)通信。
??對(duì)原項(xiàng)目入侵性:需要修改現(xiàn)有Android項(xiàng)目的Application類繼承于HarmonyApplication。

6. 總結(jié)


??鴻蒙平臺(tái)具有豐富的特性:流轉(zhuǎn),原子化服務(wù),系統(tǒng)級(jí)AI接口(文字識(shí)別,語音識(shí)別,關(guān)鍵字提取等),分布式數(shù)據(jù)服務(wù),分布式文件服務(wù)等,這些大部分是當(dāng)前Android平臺(tái)所沒有的。

??當(dāng)然如果需要基于鴻蒙平臺(tái)重新開發(fā)一個(gè)完整應(yīng)用,成本也是很大的,特別是對(duì)于一些大型應(yīng)用。因此除了上述的混合打包方案之外,目前官方主推的一種快速適配方案是單獨(dú)開發(fā)一個(gè)獨(dú)立服務(wù)卡片,然后通過服務(wù)卡片與原生應(yīng)用通信。不過獨(dú)立服務(wù)卡片的能力有限,不能充分使用鴻蒙平臺(tái)的特性。因此一般的做法是在獨(dú)立服務(wù)卡片提供一些簡(jiǎn)單的功能,然后引導(dǎo)用戶跳轉(zhuǎn)到Android原生的應(yīng)用去。

??總的來說,當(dāng)前還沒有較為方便可靠的方案支持Android原生應(yīng)用適配鴻蒙平臺(tái),或許我們應(yīng)該重新理解一下鴻蒙,其打造一套全新的開發(fā)框架和開發(fā)工具,提供豐富的平臺(tái)特性和鴻蒙系的跨平臺(tái)能力,目的就是希望未來能完全脫離原生Android系統(tǒng)。

7. 參考文獻(xiàn)


OpenHarmony
鴻蒙應(yīng)用開發(fā)者文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容