开天辟地 HarmonyOS(鸿蒙) - 开发基础: HAP(Harmony Ability Package)
开天辟地 HarmonyOS(鸿蒙) - 开发基础: HAP(Harmony Ability Package)
示例如下:
pages\basic\HapDemo.ets
/*
* HAP(Harmony Ability Package) - 应用安装和运行的基本单元
*
* 每个 HAP 都会对应一个 AbilityStage,需要在 module.json5 中的 module 的 srcEntry 中配置对应的 AbilityStage 的代码的地址
* 当前 HAP 对应的 AbilityStage 请参见 /entry/src/main/ets/entryability/MyAbilityStage.ets 中的代码
*/
import { TitleBar } from '../TitleBar';
import { common, Want } from '@kit.AbilityKit';
@Entry
@Component
struct HapDemo {
build() {
Column() {
TitleBar()
Tabs() {
TabContent() { MySample1() }.tabBar('基础').align(Alignment.Top)
}
.scrollable(true)
.barMode(BarMode.Scrollable)
.layoutWeight(1)
}
}
}
/*
* HAP(Harmony Ability Package)是应用安装和运行的基本单元,其有两种类型,分别为 entry 模块和 feature 模块
* entry - 主模块,作为应用的入口,基础功能都应该放在这里,每个应用只能有一个 entry 模块
* feature - 特性模块,应用的扩展能力可以放在这里,其可以根据用户的需求和设备类型进行选择性安装,每个应用可以包含多个 feature 模块
* 每个 hap 可以包含多个 UIAbility,每个 UIAbility 可以包含多个页面
* 右键单击全局项目,然后 New -> Module... -> Empty Ability 即可创建新的模块,一个项目包含的模块和模块的地址是在项目的 build-profile.json5 中配置的
* 如需调试,则先选择需要运行的模块,然后点击运行即可(注:当 feature 更新后,需要先运行它,这样才能从 entry 跳转到更新后的 feature)
* 如需编译打包,则在 Build 菜单中,可以编译每个 hap 包(编译后每个 hap 模块都会生成一个对应的 .hap 文件),也可以把所有 hap 打包为一个 app(编译后是一个 .app 文件)
*/
@Component
struct MySample1 {
context = getContext() as common.UIAbilityContext;
build() {
Column({ space: 10 }) {
// 打开的 feature ability 的代码请参见 /feature1/src/main/ets/feature1ability/Feature1Ability.ets 和 /feature1/src/main/ets/pages/Index.ets
Button("打开指定的 feature ability").onClick(() => {
// Want - 需要拉起的 ability 的相关信息
let want: Want = {
deviceId: '', // 空代表本设备
bundleName: 'com.webabcd.harmonydemo', // 需要打开的 feature ability 的 bundle 的名称
moduleName: 'feature1', // 需要打开的 feature ability 的 module 的名称
abilityName: 'com.webabcd.harmonydemo.Feature1Ability', // 需要打开的 feature ability 的名称(此名称是在 module.json5 中配置的)
parameters: { // 传参
'k1': 'v1',
'k2': 'v2',
}
};
// context.startAbility() - 拉起指定的 ability
this.context.startAbility(want);
})
}
}
}
\entry\src\main\ets\entryability\MyAbilityStage.ets
/*
* AbilityStage - 每个 HAP 都会对应一个 AbilityStage
* 需要在 module.json5 中的 module 的 srcEntry 中配置对应的 AbilityStage 的代码的地址
*/
import { AbilityStage, Want } from '@kit.AbilityKit';
export default class MyAbilityStage extends AbilityStage {
// 创建完成时的回调(注:加载 HAP 的入口 UIAbility 实例之前会先创建 AbilityStage 实例)
onCreate() {
}
// 当 UIAbility 以 specified 的方式启动时,就会走到 HAP 的对应的 AbilityStage 中的 onAcceptWant() 回调
onAcceptWant(want: Want): string {
// 返回 specified 标识
// 如果相同 specified 标识的 UIAbility 已存在,则热启动它(启动已存在的实例)
// 如果相同 specified 标识的 UIAbility 不存在,则冷启动它(创建新的实例,并启动)
return `${want.parameters?.specifiedKey ?? ""}`
}
}
\feature1\src\main\ets\feature1ability\Feature1Ability.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
export default class Feature1Ability extends UIAbility {
want: Want | undefined
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.want = want
}
onDestroy(): void {
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// 获取通过 Want 传递过来的数据
let k1 = this.want?.parameters?.k1
let k2 = this.want?.parameters?.k2
// 通过 LocalStorage 将数据传递给页面
let storage = LocalStorage.getShared()
storage.setOrCreate("k1", k1)
storage.setOrCreate("k2", k2)
windowStage.loadContent('pages/Index', storage);
}
onWindowStageDestroy(): void {
}
onForeground(): void {
}
onBackground(): void {
}
}
\feature1\src\main\ets\pages\Index.ets
let storage: LocalStorage = LocalStorage.getShared()
@Entry(storage)
@Component
struct Index {
@State message: string = 'hello feature1\n';
aboutToAppear(): void {
// 获取 LocalStorage 中的数据(本例会在 UIAbility 中通过 windowStage.loadContent(path, localStorage) 传递 Want 中的数据)
this.message += `k1: ${storage.get("k1")}\n`
this.message += `k2: ${storage.get("k2")}`
}
build() {
Row() {
Column() {
Text(this.message)
.fontSize(36)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步