HSP(Harmony Shared Package)是动态共享包,可以包含代码、C++库、资源和配置文件,通过HSP可以实现代码和资源的共享。HSP不支持独立发布,而是跟随其宿主应用的APP包一起发布,与宿主应用同进程,具有相同的包名和生命周期。
说明
应用内HSP:在编译过程中与应用包名(bundleName)强耦合,只能给某个特定的应用使用。
集成态HSP:构建、发布过程中,不与特定的应用包名耦合;使用时,工具链支持自动将集成态HSP的包名替换成宿主应用包名。
多个HAP/HSP共用的代码和资源放在同一个HSP中,可以提高代码、资源的可重用性和可维护性,同时编译打包时也只保留一份HSP代码和资源,能够有效控制应用包大小。
HSP在运行时按需加载,有助于提升应用性能。
同一个组织内部的多个应用之间,可以使用集成态HSP实现代码和资源的共享。
通过DevEco Studio创建一个HSP模块,我们以创建一个名为library的HSP模块为例。基本的工程目录结构如下:
MyApplication
├── library
│ ├── src
│ │ └── main
│ │ ├── ets
│ │ │ └── pages
│ │ │ └── index.ets
│ │ ├── resources
│ │ └── module.json5
│ ├── oh-package.json5
│ ├── index.ets
│ └── build-profile.json5 //模块级
└── build-profile.json5 //工程级
介绍如何导出HSP的ArkUI组件、接口、资源,供应用内的其他HAP/HSP引用。
ArkUI组件可以通过export导出,例如:
// library/src/main/ets/components/MyTitleBar.ets
@Component
export struct MyTitleBar {
build() {
Row() {
Text($r('app.string.library_title'))
.id('library')
.fontFamily('HarmonyHeiTi')
.fontWeight(FontWeight.Bold)
.fontSize(32)
.fontColor($r('app.color.text_color'))
}
.width('100%')
}
}
对外暴露的接口,需要在入口文件index.ets中声明:
// library/index.ets
export { MyTitleBar } from './src/main/ets/components/MyTitleBar';
通过export导出ts类和方法,例如:
// library/src/main/ets/utils/test.ets
export class Log {
static info(msg: string): void {
console.info(msg);
}
}
export function add(a: number, b: number): number {
return a + b;
}
export function minus(a: number, b: number): number {
return a - b;
}
对外暴露的接口,需要在入口文件index.ets中声明:
// library/index.ets
export { Log, add, minus } from './src/main/ets/utils/test';
在HSP中也可以包含C++编写的so。对于so中的native方法,HSP通过间接的方式导出,以导出liblibrary.so的乘法接口multi为例:
// library/src/main/ets/utils/nativeTest.ets
import native from 'liblibrary.so';
export function nativeMulti(a: number, b: number): number {
let result: number = native.multi(a, b);
return result;
}
对外暴露的接口,需要在入口文件index.ets中声明:
// library/index.ets
export { nativeMulti } from './src/main/ets/utils/nativeTest';
在组件中,经常需要使用字符串、图片等资源。HSP中的组件需要使用资源时,一般将其所用资源放在HSP包内,而非放在HSP的使用方处,以符合高内聚低耦合的原则。
在工程中,常通过$r/$rawfile的形式引用应用资源。可以用$r/$rawfile访问本模块resources目录下的资源,如访问resources目录下定义的图片src/main/resources/base/media/example.png时,可以用$r("app.media.example")。
不推荐使用相对路径的方式,容易引用错误路径。例如:
当要引用上述同一图片资源时,在HSP模块中使用Image("../../resources/base/media/example.png"),实际上该Image组件访问的是HSP调用方(如entry)下的资源entry/src/main/resources/base/media/example.png。
// library/src/main/ets/pages/Index.ets
// 正确用例
Image($r('app.media.example'))
.id('example')
.borderRadius('48px')
// 错误用例
Image("../../resources/base/media/example.png")
.id('example')
.borderRadius('48px')