-
概述
鸿蒙中有两种共享包,HAR(Harmony Archive)静态共享包和HSP(Harmony Shared Package)动态共享包。
HAR与HSP都是为了实现代码和资源的共享,都可以包含代码、C++库、资源和配置文件,最大的不同之处在于:HAR中的代码和资源跟随使用方编译,如果有多个使用方,它们的编译产物中会存在多份相同拷贝;而HSP中的代码和资源可以独立编译,运行时在一个进程中代码也只会存在一份。
HAR和HSP在APP包中的形态示意图
-
HSP
使用IDE的SharedLibrary模板创建后,结构如下:
HSP目录结构
在其中的oh-package.json5中:
{ "license": "Apache-2.0", "devDependencies": {}, "author": "", "name": "my_shared_library", "description": "Please describe the basic information.", "main": "Index.ets", "version": "1.0.0", "dependencies": {} }有一个main属性,在这个属性指定的文件中export需要的组件和类(包括native类),这个文件名字随便起,但是文件一定要放在该HSP的根目录下(
基于DevEco Studio4.0.3.700)。在main指定的Index.ets中:
export { MyHsp } from './src/main/ets/pages/Index'这里export了一个组件,其中MyHsp是组件名。这样一来,使用方就可以import它来使用了。
它的module.json5中:
{ "module": { "name": "my_shared_library", "type": "shared", "description": "$string:shared_desc", "deviceTypes": [ "phone", "tablet", "2in1" ], //标识当前Module是否在用户主动安装的时候安装,表示该Module对应的HAP是否跟随应用一起安装。- true:主动安装时安装。- false:主动安装时不安装。 "deliveryWithInstall": true, "pages": "$profile:main_pages" } }注意这里的type是shared。
-
HAR
使用IDE的StaticLibrary模板创建后,结构如下:
截屏2023-12-28 16.50.17.png
和HSP一样,它的oh-package.json5中的main属性指定export文件,在其中配置需要export的组件和类。
它的module.json5中:
{ "module": { "name": "har2", "type": "har", "deviceTypes": [ "default", "tablet", "2in1" ] } }type是har。
-
依赖和导入
使用HSP和HAR也很简单,在使用方module下(一般是entry)的oh-package.json5中:
{ "license": "", //这个是用于开发过程中使用的依赖工具,不会打包到HAP中 "devDependencies": {}, "author": "", "name": "entry", "description": "Please describe the basic information.", "main": "", "version": "1.0.0", "dependencies": { //本地依赖的key可以是自定义,最终会在oh_modules下生成 "my-shared-library": "file:../my_shared_library", "har1": "file:../har1", "har2": "file:../har2" } }在dependencies属性下添加依赖项,前面的key可以自定义,value指定对应共享包module的相对路径,然后根据IDE的提示进行ohpm的安装,比如上面的依赖项定义好,build后会在使用方module下的oh_modules目录下生成对应的依赖目录:
截屏2023-12-28 15.09.41.png
注意,key会作为依赖项的最终导入名,下面我们来看导入。
import {MyHsp} from 'my-shared-library' //如果都导入的话 import('my-shared-library') //导入har import {Har1Page} from 'har1'可以看到,这里可以导入部分,也可以导入所有export的组件和类。注意看from后面的信息,这个就是前面dependencies中指定的key值,他们是一一对应的。(测试的时候需要用真机或者模拟器,previewer暂不支持共享包调用效果)
-
命名路由
对应module内的路由导航,我们通常使用profile指定的路由表进行,但是在module之间的路由导航时通常使用命名路由来完成。
router.pushNamedRoute({ name: 'MyHSP' }, (err) => { if (err) { console.error(`pushNamedRoute failed, code is ${err.code}, message is ${err.message}`); return; } console.info('pushNamedRoute success'); })比如在一个HSP中的Entry组件的@Entry属性上定义一个路由名字:
@Entry({ routeName: 'MyHSP' }) @Component export struct MyHsp { ... }然后在跳转处导入:
import('my-shared-library')还有一种方式,即如果使用如下的导入方式的话:
import {MyHsp} from 'my-shared-library'则MyHsp组件必须保证在组件树中使用了,如果没使用的话进行路由跳转则会失败。当然上面的导航需要依赖好共享包之后才能跳转,在IDE的测试时需要在该处配置好依赖module,否则会报错:
截屏2023-12-28 15.23.38.png
截屏2023-12-28 15.24.53.png
其实,命名路由还可以进行同一module内的路由跳转:
import('./Demo1')比如这里的Demo1文件存在于调用方同一目录下时的引入方式。但是对于同一module内的导航来说,这种方式有些画蛇添足,因为它需要多一步手动导入的过程,不如直接使用路由表跳转来的简单、整洁。











网友评论