当前位置: 首页 > news >正文

HarmonyOS 启动模式实战:singleton、multiton 与 specified 怎么选?

文章目录

    • 前言
    • 一、三种启动模式概述
      • 1.1 启动模式是什么?
      • 1.2 三种启动模式对比
    • 二、启动模式的配置方法
      • 2.1 在 module.json5 中配置
      • 2.2 launchType 相关属性说明
    • 三、指定实例模式(specified):自定义实例分发
      • 3.1 为什么需要指定实例?
      • 3.2 实现步骤
      • 3.3 启动指定实例 Ability
    • 四、三种模式的适用场景分析
      • 4.1 如何选择启动模式?
      • 4.2 场景对比速查表
    • 五、启动模式与 Want 参数
      • 5.1 什么是 Want?
      • 5.2 Want 核心属性说明
      • 5.3 如何传递参数并在目标 Ability 中接收?
    • 总结
      • 三种模式核心速查
      • 3 个关键结论

前言

想象一下,你管理着一家连锁餐厅。现在有三种经营策略:

  • 策略 A:全国只开一家旗舰店,所有客人来都去这一家。这叫单实例(singleton)。
  • 策略 B:每座城市开一家分店,客人各去各城市的店。这叫多实例(multiton)。
  • 策略 C:根据客人的会员等级决定去哪家店——同一个 VIP 客人始终去固定那家,不同 VIP 去不同的店。这叫指定实例(specified)。

在 HarmonyOS 中,UIAbility 的启动模式(LaunchType)就是这套"经营策略"。选对启动模式,能让应用既省资源又体验流畅。本文将结合源码,讲清楚三种模式的行为差异、配置方法和适用场景。

一、三种启动模式概述

1.1 启动模式是什么?

在 HarmonyOS 中,UIAbility是应用的基本组件单元。当你从桌面点击图标、点击通知、扫码打开应用时,系统需要决定"如何启动这个 Ability"——是每次都创建新的,还是复用已有的?启动模式就是这个决策规则。

1.2 三种启动模式对比

启动模式配置值行为描述典型适用场景
单实例模式singleton全局只存在一个实例,再次启动时触发onNewWant而非onCreate应用主页、设置页
多实例模式multiton每次启动都创建新实例,各实例互相独立文档编辑器、多文件查看
指定实例模式specified由开发者通过AbilityStage.onAcceptWant自定义分发规则聊天会话、订单详情页

一句话总结singleton无论启动多少次只有一个实例;multiton每次启动都产生新实例;specified由开发者决定——同一个标识复用已有实例,不同标识创建新实例。


二、启动模式的配置方法

2.1 在 module.json5 中配置

每个UIAbility都在module.json5中声明自己的启动模式,通过launchType字段指定:

{"module":{"abilities":[{"name":"EntryAbility","srcEntry":"./ets/entryability/EntryAbility.ets","description":"$string:EntryAbility_desc","icon":"$media:icon","label":"$string:EntryAbility_label","startWindowIcon":"$media:icon","startWindowBackground":"$color:start_window_background","launchType":"singleton"},{"name":"WorkAbility","srcEntry":"./ets/workability/WorkAbility.ets","description":"$string:WorkAbility_desc","icon":"$media:icon","label":"$string:WorkAbility_label","startWindowIcon":"$media:icon","startWindowBackground":"$color:start_window_background","launchType":"multiton"},{"name":"SessionAbility","srcEntry":"./ets/sessionability/SessionAbility.ets","description":"$string:SessionAbility_desc","icon":"$media:icon","label":"$string:SessionAbility_label","startWindowIcon":"$media:icon","startWindowBackground":"$color:start_window_background","launchType":"specified"}]}}
  • "launchType": "singleton":单实例,应用内只会有一个该 Ability 实例。
  • "launchType": "multiton":多实例,每次调用startAbility()都会创建新实例。
  • "launchType": "specified":指定实例,需配合AbilityStage.onAcceptWant()自定义分发规则。

注意module.json5是标准 JSON 格式,不支持注释。实际使用时请删除所有注释行。

2.2 launchType 相关属性说明

属性名类型必填说明
launchTypestringAbility 启动模式,取值:singleton/multiton/specified
srcEntrystringAbility 对应的 ArkTS 源码路径
namestringAbility 的唯一名称,全应用内不可重复
descriptionstringAbility 的描述信息

三、指定实例模式(specified):自定义实例分发

3.1 为什么需要指定实例?

大白话理解:微信聊天列表里,每打开一个聊天窗口(比如和"张三"的聊天),微信不会每次都新建一个进程,而是根据聊天对象决定:和张三聊就复用"张三聊天窗口",和李四聊就创建一个新窗口。

这种"根据业务标识决定是否复用"的场景,就是specified模式的用武之地。

3.2 实现步骤

specified模式需要两步配合:

第一步:在module.json5中将目标 Ability 的launchType设为specified

{"abilities":[{"name":"ChatAbility","srcEntry":"./ets/chatability/ChatAbility.ets","launchType":"specified"}]}

第二步:在AbilityStage中重写onAcceptWant回调,定义实例分发规则:

// AbilityStage.etsimport{AbilityStage,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';constTAG='ChatAbilityStage';constDOMAIN=0x0000;exportdefaultclassChatAbilityStageextendsAbilityStage{/** * 当 launchType 为 specified 的 Ability 被启动时,系统调用此方法, * 询问开发者:应该使用哪个实例? * 返回值作为实例标识:相同标识复用已有实例(触发 onNewWant), * 不同标识创建新实例(触发 onCreate)。 */onAcceptWant(want:Want):string{hilog.info(DOMAIN,TAG,'ChatAbilityStage onAcceptWant');// 从 want.parameters 中提取业务标识(如会话ID、订单号等)constsessionId=want.parameters?.sessionIdasstring;if(sessionId){// 返回含 sessionId 的字符串作为实例标识return`ChatAbility_${sessionId}`;}// 没有 sessionId 时,返回默认标识(所有未指定会话共用一个实例)return'ChatAbility_default';}}

要点说明

  • onAcceptWant仅在specified模式的 Ability 被启动时触发,其他模式不会调用。
  • want.parameters中提取业务标识(会话 ID、订单号等),返回值决定实例的唯一性
  • 返回相同字符串 → 复用已有实例(触发onNewWant);返回不同字符串 → 创建新实例(触发onCreate)。
  • 返回值格式由开发者自行定义,但同一业务实体必须始终返回相同的字符串,否则会创建重复实例。

3.3 启动指定实例 Ability

import{common,Want}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';constDOMAIN=0x0000;// 从 UIAbility 的 context 发起启动letcontext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;// 构建 Want,parameters 中带上业务标识letwant:Want={deviceId:'',// 空字符串表示本设备bundleName:'com.example.myapp',abilityName:'ChatAbility',parameters:{sessionId:'user_12345_chat_001'// 业务标识,决定是否复用实例}};// 启动 ChatAbilitycontext.startAbility(want).then(()=>{hilog.info(DOMAIN,'testTag','启动聊天窗口成功');}).catch((err:Error)=>{hilog.error(DOMAIN,'testTag','启动失败: %{public}s',JSON.stringify(err));});

四、三种模式的适用场景分析

4.1 如何选择启动模式?

核心判断逻辑:

  1. 不需要多个实例→ 选singleton(绝大多数页面)
  2. 需要多个实例,由用户主动创建→ 选multiton(如文档编辑器)
  3. 需要多个实例,由业务数据驱动→ 选specified(如聊天会话、订单详情)

4.2 场景对比速查表

业务场景推荐模式理由
应用主页(首页)singleton全局唯一,复用更省资源
设置页singleton无需多开
视频播放器singleton同时只需一个播放实例
文档编辑器(多文档)multiton用户主动同时打开多份文档
文件管理器(多窗口)multiton每个文件对应独立窗口
社交应用聊天窗口specified每个会话对应固定实例
购物应用订单详情specified每个订单对应固定实例
邮件阅读页specified每封邮件对应固定实例

五、启动模式与 Want 参数

5.1 什么是 Want?

在 HarmonyOS 中,Want是一个"启动意图"对象,类似于一张"任务卡"——上面写着要执行什么操作(action)、要启动哪个 Ability(abilityName)、要传递什么数据(parameters)。

letwant:Want={deviceId:'device_001',// 目标设备 ID(本设备填空字符串)bundleName:'com.example.myapp',// 目标应用包名abilityName:'DetailAbility',// 目标 Ability 名称action:'action.detail',// 操作类型(可选)uri:'http://example.com',// 数据 URI(可选)parameters:{// 传递给 Ability 的自定义参数id:'12345',from:'home'}};

5.2 Want 核心属性说明

属性名类型说明示例值
deviceIdstring目标设备 ID,空字符串表示本设备''
bundleNamestring目标应用的包名'com.example.app'
abilityNamestring目标 Ability 的名称'DetailAbility'
actionstring操作类型(可选)'ohos.want.action.viewData'
uristring数据 URI(可选)'http://example.com'
parametersobject自定义参数,传递给目标 Ability{ id: '123' }

5.3 如何传递参数并在目标 Ability 中接收?

// ——— 发起方:启动 Ability 并传递参数 ———letwant:Want={bundleName:'com.example.myapp',abilityName:'DetailAbility',parameters:{productId:'PROD_001',// 商品 IDfrom:'recommendation',// 来源页面extraData:{// 嵌套数据对象discount:0.8,userId:'U10086'}}};context.startAbility(want).then(()=>{hilog.info(DOMAIN,'testTag','启动成功');});// ——— 接收方:在 DetailAbility 的 onCreate / onNewWant 中读取参数 ———onCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{constproductId=want.parameters?.productIdasstring;constfrom=want.parameters?.fromasstring;constextraData=want.parameters?.extraDataasRecord<string,Object>;hilog.info(DOMAIN,'testTag',`productId=${productId}, from=${from}`);}

提示want.parameters中的值类型为Object,读取时需要手动类型断言(as stringas number等)。建议在接收方做类型校验,避免因参数缺失导致运行时报错。


总结

三种模式核心速查

模式实例数量再次启动的回调需要额外配置
singleton全局唯一onNewWant
multiton每次新建onCreate
specified按标识决定已有实例:onNewWant;新实例:onCreate需实现AbilityStage.onAcceptWant

3 个关键结论

  1. onCreatevsonNewWant:实例首次创建时调用onCreate,已有实例被再次唤起时调用onNewWantsingletonspecified(复用时)都会触发onNewWant,而multiton每次都触发onCreate

  2. specified模式的核心是onAcceptWant的返回值:相同返回值 → 复用实例;不同返回值 → 新建实例。返回值需要与业务标识严格对应,否则会产生重复实例。

  3. 资源消耗排序multiton>specified>singleton。多实例模式每个实例都持有独立资源,在设备内存紧张时更容易被系统回收。

http://www.cnnetsun.cn/news/2082882.html

相关文章:

  • LFM2.5-1.2B-Instruct效果展示:system/user/assistant三段式结构稳定性
  • IgH EtherCAT 从入门到精通:第 20 章 数据报文与通信机制
  • 用Vue 2.7 + SpringBoot 3.1 + MySQL 8 从零搭建一个超市商品管理系统(附完整源码和数据库脚本)
  • GitHub Copilot SDK实战:从API调用到智能代码审查助手开发
  • GitHub 一夜爆火!这个项目解决了 AI 编程最大的坑:没有记忆
  • 抖音下载神器:如何一键批量保存无水印视频和直播回放?
  • Vivado 2023.2版本实战:从“Labtools 27-3303”到“Place 30-602”,一次解决时钟与烧录难题
  • Redis怎样利用Lua脚本批量抓取多类型数据
  • copyKAT实战:从单细胞转录组数据自动识别肿瘤细胞CNV与亚克隆结构
  • 告别AC5!在Keil MDK AC6环境下为STM32配置串口打印(Retarget详解)
  • 别再踩坑了!Docker容器里用systemctl报错Failed to get D-Bus connection的完整解决手册
  • League Akari终极指南:英雄联盟本地自动化工具完整使用教程
  • 别再只盯着USB和HDMI了!聊聊LVDS这个‘老将’为什么在工业屏和医疗设备里依然能打
  • 3个魔法步骤:让Windows 11完美运行20年前的经典游戏
  • 从零开始:如何快速掌握Switch大气层系统1.7.1完整安装指南
  • 基于scikit-learn的轻量级手语识别系统实践
  • 如何在Windows 11上完美运行DirectX 1-7经典游戏:DDrawCompat终极兼容方案
  • Zotero PDF Translate:你的学术翻译助手到底有多强大?
  • 给Linux小白的模块管理指南:从插U盘到装显卡驱动,都离不开modprobe
  • SpringAI实战:基于MCP协议的AI Agent工具链集成指南
  • 3个智能功能彻底改变你的英雄联盟游戏体验
  • STM32H7的MPU实战:用内存保护单元给你的代码加把锁,防止数组越界和野指针
  • 终极B站会员购抢票指南:biliTickerBuy帮你告别手速焦虑![特殊字符]
  • 【无人机】固定翼无人机简化燃油燃烧仿真的模拟模型(Matlab代码实现)
  • [Rust][RISCV] 一、用 Rust 写 RISC-V BootROM —— 你需要知道的 Rust 基础
  • 抖音内容批量下载实战:从单视频到直播回放的完整解决方案
  • E-Hentai批量下载终极指南:如何一键保存整个漫画图库
  • 当你的STM32项目有10个IIC设备,8个地址还一样?试试这个C语言‘面向对象’的软件IIC驱动方案
  • 小红书下载器终极教程:3分钟上手批量下载无水印图文视频
  • 暗黑破坏神2角色存档编辑器:Diablo Edit2完全指南