鸿蒙 Stage模型-应用组件-配置、UIAbility

前提:基于官网3.1/4.0文档。参考官网文档
基于Android开发体系来进行比较和思考。(或有偏颇,自行斟酌)

一、概念

在这里插入图片描述
可以看到分为运行期、编译器,主要关注UIAbility(类似Activity,UI相关)、ExtensionAbility(其他非UI相关)。
另外AbilityState暂时不确定是类似Android 中的Application。

为什么会单独有个Stage模型?
其实就是整体架构,只不过为了区分另外一个```Feature模型``,后者已经不主推。

二、模块

1.配置

.json5文件为配置文件,分为:
app.json5:app级别的配置
module.json5:模块级别的配置

示例:

{"module": {// ..."abilities": [{// $开头的为资源值"icon": "$media:icon","label": "$string:EntryAbility_label","skills": [{"entities": ["entity.system.home"],"actions": ["action.system.home"]}],}]}
}

通过json文件来配置,也是和之前

2.UIAbility

是什么?
类似Activity

1.生命周期

在这里插入图片描述

onNewIntent等生命周期是否有?
有,见如下

2.启动模式

singleton(单实例模式):与Android一致,配置文件中配置
multiton(多实例模式):对应Android的standard
specified(指定实例模式):对Ability标记key,一致的key则是统一Ability。

针对第三种模式示例:
1.配置

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

2.启动

// 在启动指定实例模式的UIAbility时,给每一个UIAbility实例配置一个独立的Key标识
// 例如在文档使用场景中,可以用文档路径作为Key标识
function getInstance() {// ...
}let want = {deviceId: '', // deviceId为空表示本设备bundleName: 'com.example.myapplication',abilityName: 'FuncAbility',moduleName: 'module1', // moduleName非必选parameters: { // 自定义信息instanceKey: getInstance(),},
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(want).then(() => {// ...
}).catch((err) => {// ...
})

这里可以看到,startAbility=startActivity,传递的数据的方式也是类似。

3.监听

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

接受参数是通过onAcceptWant获取,名称也是较为直接。

应用的UIAbility实例已创建,该UIAbility配置为指定实例模式,再次调用startAbility()方法启动该UIAbility实例,且AbilityStage的onAcceptWant()回调匹配到一个已创建的UIAbility实例。此时,再次启动该UIAbility时,只会进入该UIAbility的onNewWant()回调,不会进入其onCreate()和onWindowStageCreate()生命周期回调。

需要注意的是:Android中有栈顶复用模式,这里并没有提出这样的概念。因此不确认指定specified模式之后任务栈的关系,或者有没有任务栈的概念?

3.数据传递

使用EventHub进行数据通信:基于发布订阅模式来实现,事件需要先订阅后发布,订阅者收到消息后进行处理。——EventBus
使用globalThis进行数据同步:ArkTS引擎实例内部的一个全局对象,在ArkTS引擎实例内部都能访问。——全局静态变量
使用AppStorage/LocalStorage进行数据同步:ArkUI提供了AppStorage和LocalStorage两种应用级别的状态管理方案,可用于实现应用级别和UIAbility级别的数据同步。——本地缓存

1.EventHub
订阅:eventhub.on(‘event1’, this.func1);
取消订阅:this.context.eventHub.off(‘event1’);
发送事件: this.context.eventHub.emit(‘event1’);
监听事件: eventhub.on(‘event1’, this.func1);

核心要素和EventBus并无二致。
示例:

import UIAbility from '@ohos.app.ability.UIAbility';const TAG: string = '[Example].[Entry].[EntryAbility]';export default class EntryAbility extends UIAbility {func1(...data) {// 触发事件,完成相应的业务操作console.info(TAG, '1. ' + JSON.stringify(data));}onCreate(want, launch) {// 获取eventHublet eventhub = this.context.eventHub;// 执行订阅操作eventhub.on('event1', this.func1);eventhub.on('event1', (...data) => {// 触发事件,完成相应的业务操作console.info(TAG, '2. ' + JSON.stringify(data));});}
}import common from '@ohos.app.ability.common';@Entry
@Component
struct Index {private context = getContext(this) as common.UIAbilityContext;eventHubFunc() {// 不带参数触发自定义“event1”事件this.context.eventHub.emit('event1');// 带1个参数触发自定义“event1”事件this.context.eventHub.emit('event1', 1);// 带2个参数触发自定义“event1”事件this.context.eventHub.emit('event1', 2, 'test');// 开发者可以根据实际的业务场景设计事件传递的参数}// 页面展示build() {// ...}
}

有些许不同的是订阅对象的获取是内置的:let eventhub = this.context.eventHub;

2. globalThis
在这里插入图片描述

在这里插入图片描述
因为TS的特性,所以自定义属性难免会出现覆盖值的情况。这里是后来者覆盖前者。(Stage模型使用,而且FA 模型已经不主推了,因此后者不用管了)

3. APPStorage和LocalStorage

此处不再赘述。

4.页面启动

  1. 启动应用内的UIAbility及获取结果

需要注意的是,提到了如何销毁发起调用的Ability :

在FuncAbility业务完成之后,如需要停止当前UIAbility实例,在FuncAbility中通过调用terminateSelf()方法实现。

// context为需要停止的UIAbility实例的AbilityContext
this.context.terminateSelf((err) => {// ...
});

是finish方法?还是回调销毁发起startAbility的Ability?
类似Android中的finish方法。

获取返回结果的回调

let wantInfo = {deviceId: '', // deviceId为空表示本设备bundleName: 'com.example.myapplication',abilityName: 'FuncAbility',moduleName: 'module1', // moduleName非必选parameters: { // 自定义信息info: '来自EntryAbility Index页面',},
}
// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(wantInfo).then((data) => {// ...
}).catch((err) => {// ...
})
const RESULT_CODE: number = 1001;
let abilityResult = {resultCode: RESULT_CODE,want: {bundleName: 'com.example.myapplication',abilityName: 'FuncAbility',moduleName: 'module1',parameters: {info: '来自FuncAbility Index页面',},},
}
// context为被调用方UIAbility的AbilityContext
this.context.terminateSelfWithResult(abilityResult, (err) => {// ...
});
const RESULT_CODE: number = 1001;// ...// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(want).then((data) => {if (data?.resultCode === RESULT_CODE) {// 解析被调用方UIAbility返回的信息let info = data.want?.parameters?.info;// ...}
}).catch((err) => {// ...
})

从这里来看,与Android流程一致。

  1. 启动其他应用的UIAbility并获取返回结果

显式Want启动:启动一个确定应用的UIAbility,在want参数中需要设置该应用bundleName和abilityName,当需要拉起某个明确的UIAbility时,通常使用显式Want启动方式。

隐式Want启动:根据匹配条件由用户选择启动哪一个UIAbility,即不明确指出要启动哪一个UIAbility(abilityName参数未设置),在调用startAbility()方法时,其入参want中指定了一系列的entities字段(表示目标UIAbility额外的类别信息,如浏览器、视频播放器)和actions字段(表示要执行的通用操作,如查看、分享、应用详情等)等参数信息,然后由系统去分析want,并帮助找到合适的UIAbility来启动。当需要拉起其他应用的UIAbility时,开发者通常不知道用户设备中应用的安装情况,也无法确定目标应用的bundleName和abilityName,通常使用隐式Want启动方式。

这点与Android理念一致,但是Android高版本好像强制显示启动了?

示例:
1.设置action

{"module": {"abilities": [{// ..."skills": [{"entities": [// ..."entity.system.default"],"actions": [// ..."ohos.want.action.editData"]}]}]}
}

2.发起调用

let wantInfo = {deviceId: '', // deviceId为空表示本设备// uncomment line below if wish to implicitly query only in the specific bundle.// bundleName: 'com.example.myapplication',action: 'ohos.want.action.editData',// entities can be omitted.entities: ['entity.system.default'],
}// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(wantInfo).then((data) => {// ...
}).catch((err) => {// ...
})

3.被调用时处理

const RESULT_CODE: number = 1001;
let abilityResult = {resultCode: RESULT_CODE,want: {bundleName: 'com.example.myapplication',abilityName: 'EntryAbility',moduleName: 'entry',parameters: {payResult: 'OKay',},},
}
// context为被调用方UIAbility的AbilityContext
this.context.terminateSelfWithResult(abilityResult, (err) => {// ...
});

4.调用方处理返回数据

const RESULT_CODE: number = 1001;let want = {// Want参数信息
};// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(want).then((data) => {if (data?.resultCode === RESULT_CODE) {// 解析被调用方UIAbility返回的信息let payResult = data.want?.parameters?.payResult;// ...}
}).catch((err) => {// ...
})
  1. 启动UIAbility的指定页面
    其实就是针对onNewWant回调的处理,可以立即为类似触发Android中的onNewIntent的场景。(热启动)

3.ExtensionAbility组件

ExtensionAbility组件是基于特定场景提供的应用组件,以便满足更多的使用场景。
每一个具体场景对应一个ExtensionAbilityType,各类型的ExtensionAbility组件均由相应的系统服务统一管理,例如InputMethodExtensionAbility组件由输入法管理服务统一管理。当前支持的ExtensionAbility类型有:
FormExtensionAbility:FORM类型的ExtensionAbility组件,用于提供服务卡片场景相关能力。
WorkSchedulerExtensionAbility:WORK_SCHEDULER类型的ExtensionAbility组件,用于提供延迟任务注册、取消、查询的能力。

倒是不像四大组件的定义,毕竟偏向于UI 层面。

三、总结

UIAbility约等于Activity

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day09:基础入门-算法逆向散列对称非对称JS源码逆向AESDESRSASHA

目录 算法加密-概念&分类&类型 加密解密-识别特征&解密条件 解密实例-密文存储&数据传输 思维导图 章节知识点: 应用架构:Web/APP/云应用/三方服务/负载均衡等 安全产品:CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗透命令&am…

Minio容器化部署并整合SpringBoot

1、启动minio容器 docker run -p 9000:9000 -p 9090:9090 --name minio -d --restartalways -e MINIO_ACCESS_KEYminio -e MINIO_SECRET_KEYminio -v /usr/local/minio/data:/data -v /usr/local/minio/config:/root/.minio minio/minio server /data --console-addr…

Day18:信息打点-小程序应用解包反编译动态调试抓包静态分析源码架构

目录 小程序获取-各大平台&关键字搜索 小程序体验-凡科建站&模版测试上线 小程序抓包-Proxifier&BurpSuite联动 小程序逆向-解包反编译&动态调试&架构 思维导图 章节知识点 Web:语言/CMS/中间件/数据库/系统/WAF等 系统:操作系…

微信报修小程序源码

源码获取方式: 1、搜一搜 万能工具箱合集 然后点击资料库,即可获取资源 一、先看Demo(已更新至4.0.0) 想看界面图片的,辛苦你爬一下楼,点击下方查看资源,进入官方demo 二、功能介绍 1、当前版…

阿里云搭建私有docker仓库(学习)

搭建私有云仓库 首先登录后直接在页面搜索栏中搜索“容器镜像服务” 进入后直接选择个人版(可以免费使用) 选择镜像仓库后创建一个镜像仓库 在创建仓库之前我们先创建一个命名空间 然后可以再创建我们的仓库,可以与我们的github账号进行关联…

2024第十二届济南国际生物发酵产品与技术装备展览会胜利开幕

聚焦生物新产品新技术 引领生物产业发展新趋势 3月5日,2024第十二届济南国际生物发酵产品与技术装备展览会在济南市山东国际会展中心隆重举行。这次展览会,由中国生物发酵产业协会主办,山东省生物发酵产业协会协办,上海信世展览…

Zookeeper:常见的面试题和答案

1、什么是Zookeeper?它的作用是什么? 答: Zookeeper是一个开源的分布式协调服务,提供了一些基本的分布式服务,如配置管理、分布式锁、分布式队列等。其主要作用是帮助分布式应用程序进行协调和管理,确保分…

【剑指offer】C++ 翻转字符串里面的单词

目录 题目: 思路: 代码出现 结果 题目: 给定一个字符串,逐个翻转字符串中的每个单词。 示例 1: 输入: "the sky is blue" 输出: "blue is sky the" 示例 2: 输入: " hello…

289页初中级前端题助你拿下Offer,web前端开发面试技巧

HTML面试题部分 1.H5的新特性有哪些 2.Label的作用是什么?是怎么用的? 3.HTML5的form如何关闭自动完成功能 4.dom如何实现浏览器内多个标签页之间的通信? 5.实现不使用 border 画出1px高的线,在不同浏览器的标准模式与怪异模式下都 能保持一…

数字化转型导师坚鹏:银行业科技产品及零售贷款咨询方法与案例

银行业科技产品及零售贷款咨询方法与实战案例 课程背景: 数字化转型背景下,很多机构存在以下问题: 不知道银行业科技产品咨询方法? 不知道零售贷款咨询方法与案例? 不知道信贷中台咨询方法与案例? …

Redis 7.0版本主从复制机制

1、引言 Redis是一个开源、高性能、内存键值存储系统,同时也提供了数据结构服务器的功能。它支持五种主要的数据类型:字符串(String)、哈希表(Hashes)、列表(Lists)、集合&#xff…

建立网络防御时需要重点考虑的10个因素

互联网安全中心(CIS)建议企业可以从以下10个因素入手:资产管理、数据管理、安全配置、账户和访问控制管理、漏洞管理、日志管理、恶意软件防御、数据恢复、安全培训和事件响应。 1、资产管理 建立网络防御的第一步是制定企业资产和软件资产的…