模塊
一個鴻蒙應用可能包含一個或者多個功能模塊,在 DevEcoStudio 工程中可以創建對應的一個或多個 Module。Module 又分為 “Ability” 和 “Library”兩種類型,“Ability”類型的 Module 對應于編譯后的 HAP(Harmony Ability Package);“Library” 類型的 Module 對應于 HAR (Harmony Archive),或者 HSP (Harmony Shared Package)
三類模塊
HAP (Harmony Ability Package) | HAR (Harmony Archive) | HSP (Harmony Shared Package) | |
---|---|---|---|
功能說明及適用場合 | 分為 entry 和 feature;應用的功能模塊,可以獨立安裝和運行 | 靜態共享包,編譯態復用。- 多包(HAP/HSP)引用相同的 HAR 時,會造成多包間代碼和資源的重復拷貝,從而導致應用包膨大 | 動態共享包,運行時復用。- 當多包(HAP/HSP)同時引用同一個共享包時,可以避免 HAR 造成的多包間代碼和資源的重復拷貝,從而減少小應用包大小 |
支持在配置文件中聲明 UIAbility 組件與 ExtensionAbility 組件 | ? | ? | ? |
支持在配置文件中聲明 pages 頁面 | ? | ? | ? |
支持包含資源文件與.so 文件 | ? | ? | ? |
支持依賴其他 HAR 文件 | ? | ? | ? |
支持依賴其他 HSP 文件 | ? | ? | ? |
支持在設備上獨立安裝運行 | ? | ? | ? |
HAP
HAP(Harmony Ability Package)是應用安裝和運行的基本單元。HAP 包是由代碼、資源、第三方庫、配置文件等打包生成的模塊包;主要分為兩種類型:entry 和 feature:
- entry:應用的主模塊,作為應用的入口,提供了應用的基礎功能;
- feature:應用的動態特性模塊,作為應用能力的擴展,可以根據用戶的需求和設備類型進行選擇性安裝;
應用程序包可以只包含一個基礎的 entry 包,也可以包含一個基礎的 entry 包和多個功能性的 feature 包
//module.json5
{"module": {"name": "video","type": "entry","mainElement": "VideoAbility"}
}
//module.json5
{"module": {"name": "mall","type": "feature","mainElement": "MallAbility"}
}
注意:不支持導出 HAP 中的接口和 ArkUI 組件,供其他 HAR/HSP 模塊使用!!
HSP
HSP(Harmony Shared Package)是動態共享包,可以包含代碼、C++庫、資源和配置文件,通過 HSP 可以實現代碼和資源的共享。HSP 不支持獨立發布,而是跟隨其宿主應用的 APP 包一起發布,與宿主應用同進程,具有相同的包名和生命周期。主要使用場景:
- 多 HAP 或者 HSP 共用的代碼、資源可以使用 HSP,提高代碼的可重用性和可維護性;
- 按需加載,HSP 包在運行時再按需加載;
- 元服務分包及預加載;
//module.json5
{"module": {"name": "mylib01","type": "shared","deviceTypes": ["phone", "tablet"],"deliveryWithInstall": true,"pages": "$profile:main_pages"}
}
HAR
HAR(Harmony Archive)是靜態共享包,可以包含代碼、C++庫、資源和配置文件。通過 HAR 可以實現多個模塊或多個工程共享 ArkUI 組件、資源等相關代碼。使用場景:
- 導出公共 ArkUI 組件或 ts 類/方法供當前應用的其它 HAP 和 HSP 使用;
- 作為二方庫,發布到 OHPM 私倉,供公司內部其他應用使用;
- 作為三方庫,發布到 OHPM 中心倉,供其他應用使用;
//module.json5
{"module": {"name": "mylib02","type": "har","deviceTypes": ["default", "tablet"]}
}
注意:HAR 模塊默認不提供 pages,也沒有 UIAbility
HAP 模塊跳轉
模塊內跳轉
在同一個 HAP 中的多個 Page 間跳轉:多個頁面共用同一個窗口
//模塊內多個頁面間跳轉
router.pushUrl({url: "pages/Details",
});
在同一個 HAP 中的多個 UIAbility 間跳轉:每個頁面都有獨立的窗口
//模塊內多個UIAbility間跳轉
const want: Want = {deviceId: "", //可選,傳空表示本設備bundleName: "cn.baidu.myapp", //必需,應用唯一標識moduleName: "entry", //可選,模塊名稱abilityName: "ChatAbility", //必需,UIAbility名稱
};
let ctx = getContext(this) as common UIAbilityContext
ctx.startAbility(want)
跨 HAP 模塊跳轉
每個 HAP 上架到應用商店都是可以根據客戶端設備情況獨立安裝的,如果希望跳轉到其它模塊,必須在當前模塊的編譯配置中聲明“多 Hap 同時部署(Deploy Multi Hap)”
//跨多個HAP模塊跳轉
let want: Want = {deviceId: "", //傳空表示本設備bundleName: "cn.baidu.myapp", //應用唯一標識moduleName: "mall", // *******模塊名稱*********abilityName: "MallAbility", //UIAbility名稱
};let ctx = getContext(this) as common.UIAbilityContext;
ctx.startAbility(want);
跨模塊的多個頁面也都有各自的運行時窗口
使用 HSP
導出公共頁面
HSP 模塊中可以創建公共頁面,并導出,從而供多個 HAP 來使用
//mylib01/src/main/ets/pages/Login.ets
@Entry
@Component
export struct Login {build() {Row() {Column() {Text('Library Page')}.width('100%')}.height('100%')}
}
//entry/src/main/ets/pages/Index.ets
router.pushUrl({url: "@bundle:cn.baidu.myapp/mylib01/ets/pages/Login",
});
URL 格式為:
@bundle:包名/模塊名/路徑/頁面所在的文件名(不加.ets 后綴)
且“路徑”中沒有 src/main (部署態不存在這兩個目錄)!
注意:
必須在 HAP 模塊的編譯配置中聲明“多 Hap 同時部署(Deploy Multi Hap)”,其中勾選 HSP 模塊
說明:HSP 模塊中是沒有 UIAbility 的!只能運行在 HAP 提供的窗口中
導出公共組件
HSP 模塊中可以創建公共組件,并導出,從而供多個 HAP 來使用
//mylib01/src/main/ets/components/TitleBar.ets
@Preview
@Component
export struct TitleBar {build() {Row() {Text('Title Bar')}.width('100%').height(45)}
}
//mylib01/Index.ets
export { TitleBar } from "./src/main/ets/components/TitleBar";
//entry/oh-package.json5
{"dependencies": {"mylib01": "file:../mylib01"}
}
//entry/src/main/ets/pages/Index.ets
import { TitleBar } from 'mylib01'@Entry
@Component
struct Index {build() {Column() {TitleBar()}}
}
導出公共對象和方法
HSP 模塊中可以創建公共對象和方法,并導出,從而供多個 HAP 來使用
//mylib01/src/main/ets/util/Calc.ets
export function add(a: number, b: number) {return a + b;
}export function sub(a: number, b: number) {return a - b;
}
//mylib01/Index.ets
export { add, sub } from "./src/main/ets/utils/Calc";
//entry/oh-package.json5
{"dependencies": {"mylib01": "file:../mylib01"}
}
//entry/src/main/ets/pages/Index.ets
import { add } from 'mylib01'build() {Column() {Button('相加').onClick(_ => {add(10, 20)})}
}
使用 HAR
導出 pages 頁面
HAR 不支持在配置文件中聲明 pages 頁面,但是可以包含 pages 頁面,并通過命名路由的方式進行跳轉
//mylib02/src/main/ets/pages/MyPage.ets
@Entry({ routeName: 'myPage' })
@Component
export struct MyPage {build() {Row() {Text('My Page')}.width('100%').height('100%')}
}
//mylib02/Index.ets
//命名路由頁面無需導出
//entry/oh-package.json5
{"dependencies": {"mylib02": "file:../mylib02"}
}
//entry/src/main/ets/pages/Index.ets
import('mylib02/src/main/ets/pages/MyPage')@Entry
@Component
struct Index {build() {Button('跳轉到HAR中的頁面').onClick(_ => {router.pushNamedRoute({name: 'myPage', //頁面名稱params: {} //自定義的路由參數})})}
}
導出公共組件
HAR 模塊中可以創建公共組件,并導出,從而供多個 HAP 來使用
//mylib02/src/main/ets/components/TitleBar.ets
@Preview
@Component
export struct TitleBar {build() {Row() {Text('Title Bar')}.width('100%').height(45)}
}
//mylib02/Index.ets
export { TitleBar } from "./src/main/ets/components/TitleBar";
//entry/oh-package.json5
{"dependencies": {"mylib02": "file:../mylib02"}
}
//entry/src/main/ets/pages/Index.ets
import { TitleBar } from 'mylib02'@Entry
@Component
struct Index {build() {Column() {TitleBar()}}
}
導出公共對象和方法
HAR 模塊中可以創建公共對象和方法,并導出,從而供多個 HAP 來使用
//mylib02/src/main/ets/util/Calc.ets
export function add(a: number, b: number) {return a + b;
}export function sub(a: number, b: number) {return a - b;
}
//mylib02/Index.ets
export { add, sub } from "./src/main/ets/utils/Calc";
//entry/oh-package.json5
{"dependencies": {"mylib02": "file:../mylib02"}
}
//entry/src/main/ets/pages/Index.ets
import { add } from 'mylib02'build() {Column() {Button('相加').onClick(_ => {add(10, 20)})}
}