查看: 145|回复: 1

鸿蒙6.0 Ability Kit实战解析:Stage模型与组件开发全攻略

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式
Ability Kit 是鸿蒙(HarmonyOS)应用框架的核心组件,作为应用原子化服务的载体,它定义了应用的呈现方式、交互逻辑和生命周期管理。在鸿蒙 6.0 版本中,Ability Kit 迎来了深度优化:更高效的生命周期调度、增强的跨设备流转能力,以及对 HAR/HSP 模块化开发的原生支持。这些改进为构建复杂分布式应用提供了坚实基础。

本文将从 Stage 模型架构入手,通过可执行代码演示 UIAbility 生命周期、Context 体系、Want 通信机制以及 ExtensionAbility 的后台服务能力,帮助开发者快速掌握鸿蒙 6.0 的组件开发实践。

一、Stage 模型核心架构

鸿蒙应用模型经历了从 FA 模型到 Stage 模型的升级。Stage 模型在鸿蒙 3.0 引入,将应用组件划分为 UIAbility 和 ExtensionAbility 两大类,配合 AbilityStage 组件容器层,实现了更细粒度的资源管控和业务解耦。

Stage 模型采用三层架构:应用层(Application)→ 组件容器层(AbilityStage)→ 组件层(UIAbility / ExtensionAbility)。编译期每个 Module 对应一个 AbilityStage 实例,运行期按需创建 UIAbility 或 ExtensionAbility。核心优势包括多实例支持、精细化资源管控、模块化开发友好(通过 HAR 和 HSP 实现跨模块共享)。

核心概念中,HAP 是最终交付包(Entry / Feature),HAR 是静态共享包(源码编译到依赖方 bundle),HSP 是鸿蒙 6.0 主推的动态共享方案(运行时按需加载)。Context 体系分三层:ApplicationContext(应用级)、AbilityStageContext(模块级)、UIAbilityContext(组件级)。WindowStage 是 Ability 的窗口管理器,每个 UIAbility 对应一个 WindowStage 实例。

二、UIAbility 生命周期实战

UIAbility 生命周期包含六个核心回调:onCreate() → onWindowStageCreate() → onForeground() → onBackground() → onWindowStageDestroy() → onDestroy()。其中 onCreate 适合非 UI 资源初始化(数据库、网络配置);onWindowStageCreate 用于加载页面内容;onForeground / onBackground 对应前台/后台状态切换;onWindowStageDestroy 清理窗口资源;onDestroy 做最终释放。

以下是一个完整的 EntryAbility 实现,展示了每个回调的标准用法:
  1. // EntryAbility.ets - 入口Ability完整实现
  2. import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';
  3. import { window } from '@kit.ArkUI';
  4. import { hilog } from '@kit.PerformanceAnalysisKit';
  5. const TAG = 'EntryAbility';
  6. const DOMAIN = 0x0001;
  7. export default class EntryAbility extends UIAbility {
  8.   onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  9.     hilog.info(DOMAIN, TAG, 'onCreate called');
  10.     if (launchParam.launchReason === AbilityConstant.LaunchReason.APP_START) {
  11.       hilog.info(DOMAIN, TAG, '应用冷启动');
  12.     } else if (launchParam.launchReason === AbilityConstant.LaunchReason.COLD_START) {
  13.       hilog.info(DOMAIN, TAG, '组件冷启动');
  14.     }
  15.     this.initDatabase();
  16.   }
  17.   onWindowStageCreate(windowStage: window.WindowStage): void {
  18.     hilog.info(DOMAIN, TAG, 'onWindowStageCreate called');
  19.     windowStage.getMainWindow().then((win) => {
  20.       win.setWindowLayoutFullScreen(true);
  21.     });
  22.     windowStage.loadContent('pages/Index', (err, data) => {
  23.       if (err.code) {
  24.         hilog.error(DOMAIN, TAG, '页面加载失败: %{public}s', JSON.stringify(err));
  25.         return;
  26.       }
  27.       hilog.info(DOMAIN, TAG, '页面加载成功');
  28.     });
  29.   }
  30.   onForeground(): void {
  31.     hilog.info(DOMAIN, TAG, 'onForeground - 恢复前台操作');
  32.     AppStorage.setOrCreate('appState', 'foreground');
  33.   }
  34.   onBackground(): void {
  35.     hilog.info(DOMAIN, TAG, 'onBackground - 进入后台');
  36.     AppStorage.setOrCreate('appState', 'background');
  37.   }
  38.   onWindowStageDestroy(): void {
  39.     hilog.info(DOMAIN, TAG, 'onWindowStageDestroy - 清理窗口');
  40.   }
  41.   onDestroy(): void {
  42.     hilog.info(DOMAIN, TAG, 'onDestroy - 执行最终清理');
  43.     this.closeDatabase();
  44.   }
  45.   onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  46.     hilog.info(DOMAIN, TAG, 'onNewWant called');
  47.     if (launchParam.launchReason === AbilityConstant.LaunchReason.START_ABILITY) {
  48.       // 处理新的启动请求
  49.     }
  50.   }
  51.   private initDatabase(): void {
  52.     hilog.info(DOMAIN, TAG, '初始化数据库连接');
  53.   }
  54.   private closeDatabase(): void {
  55.     hilog.info(DOMAIN, TAG, '关闭数据库连接');
  56.   }
  57. }
复制代码

UIAbility 支持三种启动模式,通过 module.json5 的 launchType 配置:singleton(单实例)、standard(多实例)、specified(指定实例)。配置示例:
  1. {
  2.   "abilities": [
  3.     {
  4.       "name": "EntryAbility",
  5.       "srcEntry": "./ets/entryability/EntryAbility.ets",
  6.       "description": "$string:entryability_desc",
  7.       "icon": "$media:icon",
  8.       "label": "$string:entryability_label",
  9.       "startWindowIcon": "$media:icon",
  10.       "startWindowBackground": "$color:start_window_background",
  11.       "exported": true,
  12.       "launchType": "singleton",
  13.       "skills": [
  14.         {
  15.           "entities": ["entity.system.home"],
  16.           "actions": ["action.system.home"]
  17.         }
  18.       ]
  19.     }
  20.   ]
  21. }
复制代码

三、Context 与组件交互

Context 是访问系统能力的入口。三层关系:UIAbilityContext ⊂ AbilityStageContext ⊂ ApplicationContext。子层级可访问父层级全部能力并获得组件特有权限。

在 ArkUI 页面中,使用 getContext(this) 获取当前 UIAbilityContext,然后可启动其他 Ability、获取结果、终止自身等。以下为完整示例:
  1. // ContextDemo.ets - Context使用完整示例
  2. import { common, Want } from '@kit.AbilityKit';
  3. import { BusinessError } from '@kit.BasicServicesKit';
  4. import { hilog } from '@kit.PerformanceAnalysisKit';
  5. const TAG = 'ContextDemo';
  6. const DOMAIN = 0x0002;
  7. @Entry
  8. @Component
  9. struct ContextDemo {
  10.   private abilityContext = getContext(this) as common.UIAbilityContext;
  11.   async startTargetAbility(): Promise<void> {
  12.     let want: Want = {
  13.       bundleName: this.abilityContext.abilityInfo.bundleName,
  14.       abilityName: 'TargetAbility',
  15.       moduleName: this.abilityContext.abilityInfo.moduleName,
  16.       parameters: {
  17.         message: '来自Ability Kit的问候',
  18.         timestamp: Date.now(),
  19.         userData: {
  20.           name: 'HarmonyOS',
  21.           version: '6.0'
  22.         }
  23.       }
  24.     };
  25.     try {
  26.       this.abilityContext.startAbility(want, (err: BusinessError) => {
  27.         if (err.code) {
  28.           hilog.error(DOMAIN, TAG, '启动失败: %{public}s', err.message);
  29.           return;
  30.         }
  31.         hilog.info(DOMAIN, TAG, 'TargetAbility启动成功');
  32.       });
  33.     } catch (err) {
  34.       let error = err as BusinessError;
  35.       hilog.error(DOMAIN, TAG, '启动异常: %{public}d %{public}s', error.code, error.message);
  36.     }
  37.   }
  38.   async startByImplicitWant(): Promise<void> {
  39.     let want: Want = {
  40.       action: 'ohos.want.action.viewData',
  41.       entities: ['entity.system.browser'],
  42.       uri: 'https://www.example.com'
  43.     };
  44.     try {
  45.       await this.abilityContext.startAbility(want);
  46.     } catch (err) {
  47.       let error = err as BusinessError;
  48.       hilog.error(DOMAIN, TAG, '隐式启动失败: %{public}d', error.code);
  49.     }
  50.   }
  51.   async startForResult(): Promise<void> {
  52.     let want: Want = {
  53.       bundleName: 'com.example.target',
  54.       abilityName: 'ResultAbility',
  55.       parameters: {
  56.         requestCode: 'SELECT_IMAGE'
  57.       }
  58.     };
  59.     this.abilityContext.startAbilityForResult(want).then((result) => {
  60.       if (result.resultCode === 0) {
  61.         hilog.info(DOMAIN, TAG, '获取结果: %{public}s', JSON.stringify(result.want?.parameters));
  62.       }
  63.     }).catch((err: BusinessError) => {
  64.       hilog.error(DOMAIN, TAG, '获取结果失败: %{public}s', err.message);
  65.     });
  66.   }
  67.   terminateCurrent(): void {
  68.     this.abilityContext.terminateSelf();
  69.   }
  70.   terminateWithResult(): void {
  71.     let want: Want = {
  72.       parameters: {
  73.         result: '操作完成',
  74.         success: true
  75.       }
  76.     };
  77.     this.abilityContext.terminateSelfWithResult(want);
  78.   }
  79.   getAppContext(): void {
  80.     let appContext = this.abilityContext.getApplicationContext();
  81.     hilog.info(DOMAIN, TAG, '应用ID: %{public}s', appContext.info.bundleName);
  82.   }
  83.   build() {
  84.     Column({ space: 16 }) {
  85.       Text('Context 操作演示')
  86.         .fontSize(24).fontWeight(FontWeight.Bold).width('100%').textAlign(TextAlign.Center);
  87.       Divider().color('#E0E0E0');
  88.       Column({ space: 12 }) {
  89.         Text('启动Ability').fontSize(16).fontWeight(FontWeight.Medium).width('100%');
  90.         Button('显式启动目标Ability').width('100%').height(48)
  91.           .onClick(() => this.startTargetAbility());
  92.         Button('隐式启动浏览器').width('100%').height(48)
  93.           .onClick(() => this.startByImplicitWant());
  94.         Button('启动并获取结果').width('100%').height(48).type(ButtonType.Normal)
  95.           .onClick(() => this.startForResult());
  96.       }
  97.       Divider().color('#E0E0E0').margin({ top: 16, bottom: 16 });
  98.       Column({ space: 12 }) {
  99.         Text('终止操作').fontSize(16).fontWeight(FontWeight.Medium).width('100%');
  100.         Button('终止当前Ability').width('100%').height(48).backgroundColor(Color.Red)
  101.           .onClick(() => this.terminateCurrent());
  102.         Button('携带结果终止').width('100%').height(48).backgroundColor(Color.Orange)
  103.           .onClick(() => this.terminateWithResult());
  104.       }
  105.       Divider().color('#E0E0E0').margin({ top: 16, bottom: 16 });
  106.       Button('获取应用Context').width('100%').height(48).type(ButtonType.Normal)
  107.         .onClick(() => this.getAppContext());
  108.     }
  109.     .padding(20).width('100%').height('100%');
  110.   }
  111. }
复制代码

四、Want 通信机制

Want 是 HarmonyOS 组件间通信的核心载体,包含 bundleName、abilityName、moduleName、uri、action、entities、parameters 等字段。显式 Want 直接指定包名和能力名;隐式 Want 通过 action/entities/uri 让系统匹配,适用于跨应用调用。

以下演示显式 Want 和隐式 Want 的使用:
  1. // WantStructDemo.ets - Want使用示例
  2. import { Want, common } from '@kit.AbilityKit';
  3. import { BusinessError } from '@kit.BasicServicesKit';
  4. @Entry
  5. @Component
  6. struct WantStructDemo {
  7.   private context = getContext(this) as common.UIAbilityContext;
  8.   startExplicitAbility(): void {
  9.     const want: Want = {
  10.       bundleName: 'com.example.myapp',
  11.       abilityName: 'DetailAbility',
  12.       moduleName: 'entry',
  13.       parameters: {
  14.         id: '12345',
  15.         type: 'product',
  16.         from: 'list'
  17.       }
  18.     };
  19.     this.context.startAbility(want)
  20.       .then(() => console.info('显式启动成功'))
  21.       .catch((err: BusinessError) => console.error(`启动失败: ${err.code}`));
  22.   }
  23.   startImplicitAbility(): void {
  24.     const want: Want = {
  25.       action: 'ohos.want.action.viewData',
  26.       entities: ['entity.system.browsable'],
  27.       uri: 'https://www.harmonyos.com',
  28.       type: 'text/plain',
  29.       parameters: {
  30.         key: 'customValue'
  31.       }
  32.     };
  33.     this.context.startAbility(want)
  34.       .then(() => console.info('隐式启动成功'))
  35.       .catch((err: BusinessError) => console.error(`隐式启动失败: ${err.code}`));
  36.   }
  37.   build() {
  38.     Column({ space: 20 }) {
  39.       Text('Want 通信机制演示').fontSize(20).fontWeight(FontWeight.Bold);
  40.       Button('显式启动').onClick(() => this.startExplicitAbility());
  41.       Button('隐式启动').onClick(() => this.startImplicitAbility());
  42.     }.padding(20);
  43.   }
  44. }
复制代码

五、ExtensionAbility 扩展能力

ExtensionAbility 用于实现后台服务、自定义功能等。以 ServiceExtensionAbility 为例,它支持长时间运行的 background 任务和跨进程通信。以下示例展示了后台服务 Ability 的实现,通过 RPC 与客户端通信:
  1. // MyServiceExtensionAbility.ets - 后台服务Ability
  2. import { ServiceExtensionAbility, Want, AbilityConstant } from '@kit.AbilityKit';
  3. import { rpc } from '@kit.IPCKit';
  4. import { hilog } from '@kit.PerformanceAnalysisKit';
  5. const TAG = 'MyServiceExtension';
  6. const DOMAIN = 0x0003;
  7. class MyRemoteStub extends rpc.RemoteStub {
  8.   onRemoteRequest(code: number, data: rpc.MessageParcel): boolean {
  9.     hilog.info(DOMAIN, TAG, '收到请求: code=%{public}d', code);
  10.     switch (code) {
  11.       case 1: // 获取数据
  12.         let response = data.readString();
  13.         hilog.info(DOMAIN, TAG, '客户端数据: %{public}s', response);
  14.         break;
  15.       default:
  16.         return false;
  17.     }
  18.     return true;
  19.   }
  20. }
复制代码

实际开发中,需在 module.json5 中声明 extensionAbility,并配置后台权限。ServiceExtensionAbility 常与前台 UIAbility 配合,通过 Want 通信交互,适合处理下载、数据同步等后台任务。

总结
鸿蒙 6.0 的 Ability Kit 在 Stage 模型基础上,提供了更加精细的生命周期管理、灵活的 Context 体系以及强大的 Want 通信机制。通过本文提供的完整代码示例,开发者可以快速搭建起具备多实例、模块化、跨组件通信能力的应用。后续实践中,可结合最新 HSP 动态加载技术,进一步优化大型应用的结构和包体积。
回复

使用道具 举报

发表于 3 小时前 | 显示全部楼层

Re: 鸿蒙6.0 Ability Kit实战解析:Stage模型与组件开发全攻略

感谢楼主分享这么详细的实战解析!代码示例很清晰,特别是 onCreate 里区分冷启动类型和 onWindowStageCreate 设置全屏的逻辑,很实用。想请教一下楼主,在鸿蒙 6.0 中,HSP 动态共享包和之前的 HAR 包在使用上有什么特别注意的地方吗?另外帖子提到增强的跨设备流转能力,能否再具体说说在代码层面是怎么对接 Want 通信来实现的?期待后续更多干货!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-5 18:18 , Processed in 0.034031 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部