梳理NEXT的工程結(jié)構(gòu)與應(yīng)用程序包結(jié)構(gòu)

?三層工程結(jié)構(gòu)

項(xiàng)目里采用的工程結(jié)構(gòu)是官方推薦的“三層工程結(jié)構(gòu)”,本質(zhì)上和Android工程里的結(jié)構(gòu)是類似的。如下圖HMOSWorld里的工程結(jié)構(gòu):

1、common(公共能力層)

該路徑下的各個(gè)module是一些公共基礎(chǔ)能力,比如工具庫(kù)、公共配置、通用常量、自定義基礎(chǔ)組件等。

common路徑下的各個(gè)module可以根據(jù)具體的module設(shè)計(jì)需求,在創(chuàng)建時(shí)可以選擇Shared Library或Static Library,選擇了Static Library創(chuàng)建的后續(xù)需編譯成一個(gè)HAR包。該路徑下的module們只可以被products或features路徑下的module依賴,不可以反向依賴。該路徑下的module之間是可以橫向調(diào)用的。

注意:a、選擇Shared Library創(chuàng)建的module,在后續(xù)編譯時(shí),會(huì)生成一個(gè).hsp文件,同時(shí)其內(nèi)部的使用export關(guān)鍵字修飾的class、interface、function等可導(dǎo)出項(xiàng)還會(huì)被組合一起打一個(gè).har包。各個(gè)宿主module通過(guò)該.har來(lái)引用HSP里的導(dǎo)出項(xiàng),但是在進(jìn)程中該HSP的代碼只有一份,大家共享。

b、選擇Static Library創(chuàng)建的module,在后續(xù)編譯時(shí),該module會(huì)被打成一個(gè)har包,凡是引用了該module里的可導(dǎo)出項(xiàng)或資源的宿主module,在后續(xù)打出的hap包里都會(huì)擁有該har包。要注意避免引入過(guò)多的無(wú)用代碼。

2、features(基礎(chǔ)特性層/業(yè)務(wù)模塊層)

該路徑下一般是各個(gè)業(yè)務(wù)模塊,各個(gè)module高內(nèi)聚、低耦合,可以供products層的各個(gè)entry選擇性地引用,以實(shí)現(xiàn)靈活地部署。不需要單獨(dú)部署的module通常會(huì)被編譯為HAR包,供products層或features層的其它module使用。需要單獨(dú)部署的module通常會(huì)被編譯為Feature類型的HAP包,和products下Entry類型的HAP包進(jìn)行組合部署。features層里的各個(gè)module可以橫向調(diào)用及依賴common層,同時(shí)可以被products層里的不同設(shè)備形態(tài)的HAP(可以認(rèn)為是不同的項(xiàng)目)所依賴,但是不能反向依賴products層里的entry module。

在創(chuàng)建時(shí),選擇前面圖中的Empty Ability,選擇feature。

3、products(產(chǎn)品定制層)

該路徑下的各個(gè)entry module是在不同的設(shè)備情況下app應(yīng)用的入口,每個(gè)module會(huì)針對(duì)不同的設(shè)備形態(tài)進(jìn)行不同的功能和特性集成。

它們各自被編譯為一個(gè)Entry類型的HAP包,作為應(yīng)用主入口。products層不可以橫向調(diào)用。

注意:整個(gè)代碼工程最終會(huì)構(gòu)建出一個(gè)APP包,應(yīng)用以APP包的形式發(fā)布到應(yīng)用市場(chǎng)中。

引用module

在工程內(nèi)上層引用下層的module時(shí)

有兩種簡(jiǎn)單的操作方式:

a、在Terminal窗口中,執(zhí)行如下命令進(jìn)行安裝,IDE會(huì)在引用方module里的oh-package.json5中自動(dòng)添加依賴。

比如entry要引用不同路徑下的utils,utils要引用同路徑下的constants:

cd entry 或 cd ../common/utils//? 切到entry module目錄下 或 切到common路徑下的utils module目錄下

ohpm install ../common/utils 或 ohpm install ../constants// 把utils module引用到entry module中 或 把同為common路徑下的constants module引用到utils module中

結(jié)果如下,在oh-package.json5文件中的dependencies里會(huì)生成依賴項(xiàng):

{

? "name": "entry",

? "version": "1.0.0",

? "description": "Please describe the basic information.",

? "main": "",

? "author": "",

? "license": "",

? "dependencies": {

? ? "@ohos/utils": "file:../common/utils"? ? ? ? ? // key為utils module的name,value是utils module的路徑

? },

? "devDependencies": {},

? "dynamicDependencies": {}

}

// 或者

{

? "name": "@ohos/utils",

? "version": "1.0.0",

? "description": "Please describe the basic information.",

? "main": "Index.ets",

? "author": "",

? "license": "Apache-2.0",

? "dependencies": {

? ? "constants": "file:../constants"? ? ? ? ? ? // key為同路徑下的constants module的name,value是constants module的路徑

? },

? "devDependencies": {},

? "dynamicDependencies": {}

}

b、直接在entry或utils下的oh-package.json5文件中手動(dòng)添加依賴項(xiàng),然后sync project。

引用社區(qū)庫(kù)時(shí)

社區(qū)庫(kù)是指由代碼貢獻(xiàn)者已經(jīng)上架到ohpm中心供其他開(kāi)發(fā)者下載使用的庫(kù),可以通過(guò)如下兩種方式設(shè)置對(duì)ohpm倉(cāng)三方包的依賴信息,這里推薦第一種。

(下面步驟以@ohos/lottie三方庫(kù)舉例):

方式一:在Terminal窗口中,執(zhí)行如下命令安裝三方包,DevEco Studio會(huì)自動(dòng)在當(dāng)前module中的oh-package.json5中自動(dòng)添加三方包依賴。

ohpm install @ohos/lottie

結(jié)果示例:

{

? "name": "entry",

? "version": "1.0.0",

? "description": "Please describe the basic information.",

? "main": "",

? "author": "",

? "license": "",

? "dependencies": {

? ? "@ohos/utils": "file:../common/utils",

? ? "@ohos/lottie": "^2.0.12"? ? ? ? // 注意:value里版本號(hào)前面有個(gè)符合^

? },

? "devDependencies": {},

? "dynamicDependencies": {}

}

方式二:在工程的某個(gè)module中的oh-package.json5文件中設(shè)置三方包依賴,配置示例如下:

"dependencies": {

? "@ohos/lottie": "^2.0.12"

}

其實(shí)是跟上面的步驟一樣的,只是手動(dòng)處理下而已。

module的name里包含@ohos

在一個(gè)module里的oh-package.json5文件中,name字段對(duì)應(yīng)的字符串值是用于設(shè)置該module的名稱的。如果名稱中包含了@ohos/這樣的字樣,表明這是一個(gè)屬于鴻蒙操作系統(tǒng)生態(tài)里(ohpm倉(cāng)庫(kù))提供的可供三方應(yīng)用使用的庫(kù)?!瓳ohos’命名標(biāo)識(shí)是用于區(qū)分是社區(qū)庫(kù)提供的模塊還是用戶工程里自定義的其他模塊。

例如,我們想要引用一個(gè)社區(qū)庫(kù)時(shí),如網(wǎng)絡(luò)模塊axios。在提供方工程的axios module里,它的oh-package.json5中的name應(yīng)該這樣寫:

{

? ? "name": "@ohos/axios",

? ? "description": "Axios ,是一個(gè)基于 promise 的網(wǎng)絡(luò)請(qǐng)求庫(kù)。本庫(kù)。。。",

? ? // ....

}

在我們的代碼中就可以通過(guò)@ohos/axios來(lái)引用這個(gè)模塊了,這有助于避免與我們自己工程里的同名模塊發(fā)生沖突,我們工程里引用axios模塊的module里的oh-package.json5文件如下:

{

? "name": "entry",

? // ...

? "dependencies": {

? ? "constants": "file:../constants",? ? ? // 自己工程里的constants module

? ? "@ohos/axios": "^2.2.3"? ? ? ? ? ? ? ? // 發(fā)布到ohos社區(qū)庫(kù)里的開(kāi)源庫(kù)axios

? }

}

應(yīng)用程序包的結(jié)構(gòu)

工程里的多module機(jī)制

在進(jìn)行應(yīng)用開(kāi)發(fā)時(shí),一個(gè)應(yīng)用工程中通常包含一個(gè)或多個(gè)Module。Module中包含了源代碼、資源文件、第三方庫(kù)及應(yīng)用/服務(wù)配置文件,每一個(gè)Module都可以獨(dú)立進(jìn)行編譯和運(yùn)行。

Module分為“Ability”和“Library”兩種類型:

“Ability”類型的Module編譯后生成HAP包,type為entry或feature。

“Library”類型的Module編譯后生成HAR包,type為har或shared,shared的同時(shí)還生成hsp包。

不同類型的hap包

HarmonyOS應(yīng)用是以APP Pack的形式發(fā)布的,app包里包含了一個(gè)或多個(gè)hap包。HAP是HarmonyOS應(yīng)用在安裝時(shí)的基本單位,HAP可以分為Entry和Feature兩種類型:

1、Entry類型的HAP:即應(yīng)用的主模塊。在同一個(gè)應(yīng)用中,同一設(shè)備類型只支持一個(gè)Entry類型的HAP,通常用于實(shí)現(xiàn)應(yīng)用的入口界面、入口圖標(biāo)、主特性功能等。

注意:不同的設(shè)備形態(tài),比如手機(jī)(phone)和平板(tablet)屬于不同的形態(tài),是分別有不同的Entry類型的hap包的,但是它們都在同一個(gè)app pack中,應(yīng)用是以pack上架應(yīng)用市場(chǎng)的,在不同的設(shè)備形態(tài)上的應(yīng)用市場(chǎng)中可以分別下載安裝各自對(duì)應(yīng)的Entry類型的hap包。

2、Feature類型的HAP:應(yīng)用的動(dòng)態(tài)特性模塊。Feature類型的HAP通常用于實(shí)現(xiàn)應(yīng)用的特性功能,一個(gè)應(yīng)用程序包可以包含一個(gè)或多個(gè)Feature類型的HAP,也可以不包含。

編譯態(tài)的包結(jié)構(gòu)

不同類型的Module編譯后會(huì)生成對(duì)應(yīng)的HAP、HAR、HSP等文件,開(kāi)發(fā)態(tài)視圖與編譯態(tài)視圖的對(duì)照關(guān)系如下:

從開(kāi)發(fā)態(tài)到編譯態(tài),一個(gè)Module中的文件會(huì)發(fā)生如下變更:

ets目錄:里面的所有ArkTS源碼會(huì)被編譯生成一個(gè).abc文件。

resources目錄:AppScope目錄下的資源文件會(huì)合入到每個(gè)Module下面的資源目錄中,如果兩個(gè)目錄下存在重名文件,編譯打包后只會(huì)保留AppScope目錄下的資源文件。

module配置文件:AppScope目錄下的app.json5文件字段會(huì)合入到每個(gè)Module下面的module.json5文件之中,編譯后生成HAP或HSP最終的module.json文件。

注意:在編譯生成HAP和HSP時(shí),會(huì)把他們所依賴的HAR包直接編譯到HAP和HSP中。

發(fā)布態(tài)的包結(jié)構(gòu)

每個(gè)應(yīng)用(app pack)中至少包含了一個(gè).hap文件,同時(shí)可能包含若干個(gè).hsp文件,也可能不含。一個(gè)應(yīng)用中的所有的.hap與.hsp文件合在一起稱為Bundle,它的bundleName字段的值是應(yīng)用的唯一標(biāo)識(shí),即安卓中常說(shuō)的包名。

當(dāng)一個(gè)應(yīng)用要發(fā)布上架到應(yīng)用市場(chǎng)時(shí),需要將Bundle打包為一個(gè).app后綴的文件用于上架,這個(gè).app文件稱為App Pack(Application Package),與此同時(shí),DevEco Studio工具會(huì)自動(dòng)生成一個(gè)pack.info文件。pack.info文件里描述了App Pack中每個(gè)HAP和HSP的屬性,包含APP中的bundleName和versionCode信息、以及每個(gè)Module中的name、type和abilities等信息。

所以,發(fā)布態(tài)的包結(jié)構(gòu)里包含了:1個(gè)entry.hap、0個(gè)或多個(gè)feature.hap、0個(gè)或多個(gè)library.hsp、pack.info。

打包-上架-下載安裝的流程如下:

注意:

1、App Pack是發(fā)布上架到應(yīng)用市場(chǎng)的基本單元,但是不能在設(shè)備上直接安裝和運(yùn)行。

2、在應(yīng)用簽名、云端分發(fā)、端側(cè)安裝時(shí),都是以HAP/HSP為單位進(jìn)行簽名、分發(fā)和安裝的。

結(jié)語(yǔ):希望每一次梳理-總結(jié)都能帶給你我一定的收獲。。。

?著作權(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)容