鸿蒙Harmony实战开发知识:“UIAbility组件的3种启动模式”

news2024/11/15 12:32:28

UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态。针对不同的业务场景,系统提供了三种启动模式:

singleton启动模式

singleton启动模式为单实例模式,也是默认情况下的启动模式。

每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。

图1 单实例模式演示效果

如果需要使用singleton启动模式,在module.json5配置文件中的launchType字段配置为singleton即可。

{
  "module": {
    ...
    "abilities": [
      {
        "launchType": "singleton",
        ...
      }
    ]
  }
}

multiton启动模式

multiton启动模式为多实例模式,每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。

图2 多实例模式演示效果

multiton启动模式的开发使用,在module.json5配置文件中的launchType字段配置为multiton即可。

{
  "module": {
    ...
    "abilities": [
      {
        "launchType": "multiton",
        ...
      }
    ]
  }
}

specified启动模式

specified启动模式为指定实例模式,针对一些特殊场景使用(例如文档应用中每次新建文档希望都能新建一个文档实例,重复打开一个已保存的文档希望打开的都是同一个文档实例)。

图3 指定实例模式演示效果

例如有两个UIAbility:EntryAbility和SpecifiedAbility,SpecifiedAbility配置为指定实例模式启动,需要从EntryAbility的页面中启动SpecifiedAbility。

  1. 在SpecifiedAbility中,将module.json5配置文件的launchType字段配置为specified。

    {
      "module": {
        ...
        "abilities": [
          {
            "launchType": "specified",
            ...
          }
        ]
      }
    }

  2. 在创建UIAbility实例之前,开发者可以为该实例指定一个唯一的字符串Key,这样在调用startAbility()方法时,应用就可以根据指定的Key来识别响应请求的UIAbility实例。在EntryAbility中,调用startAbility()方法时,可以在want参数中增加一个自定义参数,例如instanceKey,以此来区分不同的UIAbility实例。

     
     // 在启动指定实例模式的UIAbility时,给每一个UIAbility实例配置一个独立的Key标识
     // 例如在文档使用场景中,可以用文档路径作为Key标识
     import { common, Want } from '@kit.AbilityKit';
     import { hilog } from '@kit.PerformanceAnalysisKit';
     import { BusinessError } from '@kit.BasicServicesKit';
    
     const TAG: string = '[Page_StartModel]';
     const DOMAIN_NUMBER: number = 0xFF00;
    
     function getInstance(): string {
       return 'KEY';
     }
    
     @Entry
     @Component
     struct Page_StartModel {
       private KEY_NEW = 'KEY';
    
       build() {
         Row() {
           Column() {
             // ...
             Button()// ...
               .onClick(() => {
                 let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
                 // context为调用方UIAbility的UIAbilityContext;
                 let want: Want = {
                   deviceId: '', // deviceId为空表示本设备
                   bundleName: 'com.samples.stagemodelabilitydevelop',
                   abilityName: 'SpecifiedFirstAbility',
                   moduleName: 'entry', // moduleName非必选
                   parameters: {
                     // 自定义信息
                     instanceKey: this.KEY_NEW
                   }
                 };
                 context.startAbility(want).then(() => {
                   hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in starting SpecifiedAbility.');
                 }).catch((err: BusinessError) => {
                   hilog.error(DOMAIN_NUMBER, TAG, `Failed to start SpecifiedAbility. Code is ${err.code}, message is ${err.message}`);
                 })
                 this.KEY_NEW = this.KEY_NEW + 'a';
               })
             // ...
             Button()// ...
               .onClick(() => {
                 let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
                 // context为调用方UIAbility的UIAbilityContext;
                 let want: Want = {
                   deviceId: '', // deviceId为空表示本设备
                   bundleName: 'com.samples.stagemodelabilitydevelop',
                   abilityName: 'SpecifiedSecondAbility',
                   moduleName: 'entry', // moduleName非必选
                   parameters: {
                     // 自定义信息
                     instanceKey: getInstance()
                   }
                 };
                 context.startAbility(want).then(() => {
                   hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in starting SpecifiedAbility.');
                 }).catch((err: BusinessError) => {
                   hilog.error(DOMAIN_NUMBER, TAG, `Failed to start SpecifiedAbility. Code is ${err.code}, message is ${err.message}`);
                 })
                 this.KEY_NEW = this.KEY_NEW + 'a';
               })
             // ...
           }
           .width('100%')
         }
         .height('100%')
       }
     }

  3. 由于SpecifiedAbility的启动模式被配置为指定实例启动模式,因此在SpecifiedAbility启动之前,会先进入对应的AbilityStage的onAcceptWant()生命周期回调中,以获取该UIAbility实例的Key值。然后系统会自动匹配,如果存在与该UIAbility实例匹配的Key,则会启动与之绑定的UIAbility实例,并进入该UIAbility实例的onNewWant()回调函数;否则会创建一个新的UIAbility实例,并进入该UIAbility实例的onCreate()回调函数和onWindowStageCreate()回调函数。

    示例代码中,通过实现onAcceptWant()生命周期回调函数,解析传入的want参数,获取自定义参数instanceKey。业务逻辑会根据这个参数返回一个字符串Key,用于标识当前UIAbility实例。如果返回的Key已经对应一个已启动的UIAbility实例,系统会将该UIAbility实例拉回前台并获焦,而不会创建新的实例。如果返回的Key没有对应已启动的UIAbility实例,则系统会创建新的UIAbility实例并启动。

     import { AbilityStage, Want } from '@kit.AbilityKit';
    
     export default class MyAbilityStage extends AbilityStage {
       onAcceptWant(want: Want): string {
         // 在被调用方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值
         // 当前示例指的是module1 Module的SpecifiedAbility
         if (want.abilityName === 'SpecifiedFirstAbility' || want.abilityName === 'SpecifiedSecondAbility') {
           // 返回的字符串Key标识为自定义拼接的字符串内容
           if (want.parameters) {
             return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`;
           }
         }
         // ...
         return 'MyAbilityStage';
       }
     }
     

    例如在文档应用中,可以为不同的文档实例内容绑定不同的Key值。每次新建文档时,可以传入一个新的Key值(例如可以将文件的路径作为一个Key标识),此时AbilityStage中启动UIAbility时都会创建一个新的UIAbility实例;当新建的文档保存之后,回到桌面,或者新打开一个已保存的文档,回到桌面,此时再次打开该已保存的文档,此时AbilityStage中再次启动该UIAbility时,打开的仍然是之前原来已保存的文档界面。

    以如下步骤所示进行举例说明。

    1. 打开文件A,对应启动一个新的UIAbility实例,例如启动UIAbility实例1。
    2. 在最近任务列表中关闭文件A的任务进程,此时UIAbility实例1被销毁,回到桌面,再次打开文件A,此时对应启动一个新的UIAbility实例,例如启动UIAbility实例2。
    3. 回到桌面,打开文件B,此时对应启动一个新的UIAbility实例,例如启动UIAbility实例3。
    4. 回到桌面,再次打开文件A,此时仍然启动之前的UIAbility实例2,因为系统会自动匹配UIAbility实例的Key值,如果存在与之匹配的Key,则会启动与之绑定的UIAbility实例。在此例中,之前启动的UIAbility实例2与文件A绑定的Key是相同的,因此系统会拉回UIAbility实例2并让其获焦,而不会创建新的实例。

最后

小编在之前的鸿蒙系统扫盲中,有很多朋友给我留言,不同的角度的问了一些问题,我明显感觉到一点,那就是许多人参与鸿蒙开发,但是又不知道从哪里下手,因为资料太多,太杂,教授的人也多,无从选择。有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

为了确保高效学习,建议规划清晰的学习路线,涵盖以下关键阶段:


 鸿蒙(HarmonyOS NEXT)最新学习路线

该路线图包含基础技能、就业必备技能、多媒体技术、六大电商APP、进阶高级技能、实战就业级设备开发,不仅补充了华为官网未涉及的解决方案

路线图适合人群:

IT开发人员:想要拓展职业边界
零基础小白:鸿蒙爱好者,希望从0到1学习,增加一项技能。
技术提升/进阶跳槽:发展瓶颈期,提升职场竞争力,快速掌握鸿蒙技术

2.视频学习资料+学习PDF文档

HarmonyOS Next 最新全套视频教程

  纯血版鸿蒙全套学习资料(面试、文档、全套视频等)              

​​

总结

参与鸿蒙开发,你要先认清适合你的方向,如果是想从事鸿蒙应用开发方向的话,可以参考本文的学习路径,简单来说就是:为了确保高效学习,建议规划清晰的学习路线

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2053789.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

windows下的redis7.0.11的下载

天,我找redis7.0.11的安装包就找了好久,终于给我找到了。市面上好多是linux版本的。 安装包:Release Redis 7.0.11 for Windows zkteco-home/redis-windows GitHub 解压之后是这样的。 然后你要测试能不能启动: 1、指定配置文…

复现DOM型XSS攻击(1-8关)

目录 第一关:​ 分析代码: 第二关: 分析代码: 第三关: 分析代码: 第四关: 分析代码: 第五关: 分析代码: 第六关: 分析代码&#xff1…

volatitle-线程并发-小白一文速通

目录 简而言之 专业术语解释 1、可见性 原理简介 原理图解 其他方式 2、原子性 原理简介 结合实例分析 3、有序性 原理简介 线程安全问题 Volatile效果 1、保证可见性 2、保证有序性 3、无法保证原子性 Volatile底层的实现机制(重点掌握) 经典案例 Java双重检…

朗致面试----Java开发、Java架构师

一共三轮面试。第一轮是逻辑行测,第二轮是技术面试(面试官-刘老师),第三轮是CTO面试(面试官-屠老师)。第三轮Coding做完之后共享屏幕讲一个你自己负责过的项目(请提前准备好架构图,开…

【AI趋势8】具身智能

随着科技的飞速发展,人工智能(AI)已经从概念走向实际应用,深刻影响着我们的生产和生活方式。在众多AI技术载体中,人型机器人凭借其独特的类人形态和全身自由度,成为人工智能领域的终极载体之一。本文将深入…

系列:水果甜度个人手持设备检测-产品规划汇总与小结

系列:水果甜度个人手持设备检测 -- 产品规划汇总与小结 背景 接上一篇,我们从假设的用户需求出发,规划输出软硬件结合的一体化产品。在产品中搭载近红外光谱(NIR)、超声检测的模块,并针对不同的瓜果类型&#xff0c…

【开源分享】CommLite 跨平台文本UI串口调试助手

文章目录 1. 简介2. 编译3. 使用4. 借鉴&思考参考 1. 简介 CommLite是一款基于CSerialPort的文本UI串口调试助手。 gitee仓库 2. 编译 编译非常简单,按照文档操作即可: $ git clone --depth1 https://github.com/itas109/CommLite.git $ cd Comm…

数据结构----AVL树

小编会一直更新数据结构相关方面的知识,使用的语言是Java,但是其中的逻辑和思路并不影响,如果感兴趣可以关注合集。 希望大家看完之后可以自己去手敲实现一遍,同时在最后我也列出一些基本和经典的题目,可以尝试做一下。…

牛客网习题——通过C++实现

一、目标 实现下面4道练习题增强C代码能力。 1.求123...n_牛客题霸_牛客网 (nowcoder.com) 2.计算日期到天数转换_牛客题霸_牛客网 (nowcoder.com) 3.日期差值_牛客题霸_牛客网 (nowcoder.com) 4.打印日期_牛客题霸_牛客网 (nowcoder.com) 二、对目标的实现 1.求123...n_…

Java二十三种设计模式-访问者模式(21/23)

本文深入探讨了访问者模式,一种允许向对象结构添加新操作而不修改其本身的设计模式,涵盖了其定义、组成部分、实现方式、使用场景、优缺点、与其他模式的比较,以及最佳实践和替代方案。 访问者模式:为对象结构添加新的操作 引言 …

黑神话:悟空-配置推荐

显卡推荐(按类别整理) 1. GTX 10系列、GTX 16系列: 如果希望体验光线追踪,建议根据预算升级到RTX 40系列显卡。对于1080p分辨率,至少需要RTX 4060才能流畅运行。 2. RTX 20系列: RTX 2060、RTX 2070&#…

Openboxes 移动终端APP项目开发环境搭建与调试

文章目录 前言项目简介APP开发环境搭建APP开发环境启动及调试主应用程序启动及调试结语 前言 openboxes 项目还有一个针对移动端的项目:openboxes-mobile,但是这个项目的默认分支(develop)并没有与openboxes的默认分支对应&#…

LabVIEW优化内存使用

在LabVIEW中,优化内存使用的关键在于理解LabVIEW的内存管理机制并采用一些最佳实践。以下是一些可能帮助减少内存占用的方法: 1. 减少数据副本的生成 避免不必要的数据复制:每当你在程序中传递数组或子数组时,LabVIEW可能会创建副…

充电宝哪些品牌的性价比是最高的?开学最推荐入手四款充电宝

随着新学期的到来,学生们对充电宝的需求愈发迫切。无论是在校园内上课、图书馆自习,还是在外出游玩时,充电宝都成为了我们必不可少的随身装备。然而,市场上充斥着各种品牌和型号,如何选择一款性价比高的充电宝&#xf…

React+Vis.js(04):设置节点显示图片

文章目录 实现效果关键代码完整代码设置图片边框和背景颜色我们继续以 复仇者联盟为例,来介绍如何实现节点显示 图片。 实现效果 以图片进行节点的显示,使得显示效果更加直观,信息更为明了。 关键代码 在vis.js中,通过属性shape来控制节点显示为图像。 const nodes …

linux | 苹果OpenCL(提高应用软件如游戏、娱乐以及科研和医疗软件的运行速度和响应)

点击上方"蓝字"关注我们 01、引言 >>> OpenCL 1.0 于 2008 年 11 月发布。 OpenCL 是为个人电脑、服务器、移动设备以及嵌入式设备的多核系统提供并行编程开发的底层 API。OpenCL 的编程语言类似于 C 语言。其可以用于包含 CPU、GPU 以及来自主流制造商如 …

关于Hipe并发库中动态线程库DynamicThreadPond的一点解读(二)

文章目录 前提动态减少代码解读 动态增加线程池退出时发生了什么?总结附录 前提 我们在关于Hipe并发库中动态线程库DynamicThreadPond的一点解读(一)中介绍了DynamicThreadPond如何初始化,如何向任务队列中添加任务,线程池中的线程如何执行任…

机器学习——第十二章 计算学习理论

目录 12.1 基础知识 12.2 PAC学习 12.3 有限假设空间 12.3.1 可分情形 12.3.2 不可分情形 12.4 VC维 12.5 Rademacher复杂度 12.6 稳定性 12.1 基础知识 计算学习理论(computational learning theory)研究的是关于通过"计算"来进行"学习"的理论…

SAP无参考收货

其他收货 如果我们未参考其他凭证(采购订单、生产订单或预留)输入货物移动,则我们将讲到其他收货。因为在实际过帐之前,系统不会存储任何物料、数量、交货日期、接收工厂或来源方面的信息,所以此类收货属于计划外货物…

一文入门re 正则表达式

一、常用方法 (一)匹配 一般使用方法 第一个参数:正则模式 第二个参数:需要处理的字符串 第三个参数:附加处理方法result从任意位置开始匹配,返回match,没有匹配到返回None result re.searc…