启动模式与实例管理:singleton、multiton 与 specified 场景
启动模式与实例管理:singleton、multiton 与 specified 场景
主题关键词:launchType、singleton、multiton、specified、onNewWant、实例管理。

文章导读
- 适合读者:已经会创建 HarmonyOS 工程,但对 AbilityKit 工程边界、生命周期和系统能力衔接不够清晰的开发者。
- 本篇场景:通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新。
- 本篇结论:启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。
- 阅读方式:先看每节配图,再复制关键代码,最后用验收清单检查自己的项目。
目录
- 明确本节目标
- 理解官方概念
- 建立最小工程结构
- 声明 Ability 配置
- 实现生命周期入口
- 加载 ArkUI 页面
- 传递业务参数
- 读取 Context 能力
- 处理前后台切换
- 处理重复启动
- 处理异常兜底
- 释放页面资源
- 补充工程封装
- 本节小结与练习
1. 明确本节目标

场景定位
本节把 明确本节目标 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 launchType,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
launchType在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
2. 理解官方概念

场景定位
本节把 理解官方概念 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 singleton,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
singleton在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
3. 建立最小工程结构

场景定位
本节把 建立最小工程结构 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 multiton,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
multiton在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
4. 声明 Ability 配置

场景定位
本节把 声明 Ability 配置 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 specified,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
specified在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
5. 实现生命周期入口

场景定位
本节把 实现生命周期入口 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 onNewWant,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
onNewWant在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
6. 加载 ArkUI 页面

场景定位
本节把 加载 ArkUI 页面 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 实例管理,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
实例管理在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
7. 传递业务参数

场景定位
本节把 传递业务参数 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 实例管理,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
实例管理在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
8. 读取 Context 能力

场景定位
本节把 读取 Context 能力 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 实例管理,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
实例管理在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
9. 处理前后台切换

场景定位
本节把 处理前后台切换 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 实例管理,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
实例管理在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
10. 处理重复启动

场景定位
本节把 处理重复启动 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 实例管理,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
实例管理在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
11. 处理异常兜底

场景定位
本节把 处理异常兜底 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 实例管理,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
实例管理在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
12. 释放页面资源

场景定位
本节把 释放页面资源 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 实例管理,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
实例管理在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
13. 补充工程封装

场景定位
本节把 补充工程封装 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 实例管理,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
实例管理在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
14. 设计验证清单

场景定位
本节把 设计验证清单 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 实例管理,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
实例管理在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
15. 本节小结与练习

场景定位
本节把 本节小结与练习 放到「通知、桌面图标、外部链接多入口同时打开同一个应用时,控制 Ability 实例数量和参数刷新」这个真实开发场景里理解。它不是孤立 API,而是围绕 启动模式决定系统如何复用 Ability 实例;选错模式会导致页面重复、参数丢失或任务栈混乱。 展开的一个工程动作。当前关注点是 实例管理,读者可以把它当成排查 AbilityKit 项目问题时的一条检查线。
实战代码
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private currentId = '';
onCreate(want: Want): void {
this.applyWant(want, 'create');
}
onNewWant(want: Want): void {
this.applyWant(want, 'new-want');
}
private applyWant(want: Want, source: string): void {
const id = String(want.parameters?.id ?? '');
if (id && id !== this.currentId) {
this.currentId = id;
console.info(`[DetailAbility] ${source}, switch to id=${id}`);
}
}
}
代码解释
- 入口层只处理系统回调、上下文获取和启动协议,不把页面 UI 细节塞进 Ability。
- 业务参数要先校验再使用,尤其是来自通知、外部链接、卡片或跨 Ability 跳转的参数。
- 生命周期回调里必须区分“初始化一次”“每次回前台都执行”“退出时释放”三类动作。
- 日志要带上业务标识,例如 routeId、taskId、target,方便真机调试时定位问题。
常见坑
使用 singleton 后只处理 onCreate,不处理 onNewWant,第二次打开同一 Ability 时页面仍显示旧数据。
验收标准
- 能说清
实例管理在 启动模式与实例管理 中承担的职责。 - 代码能放进 DevEco Studio 工程中按小步验证,而不是只停留在伪代码。
- 异常分支、生命周期切换和资源释放都有明确处理点。
参考资料
- 华为 HarmonyOS 官方文档:AbilityKit / UIAbility / Stage 模型相关指南。
- DevEco Studio 真机调试日志和 ArkTS 工程结构。
更多推荐




所有评论(0)