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

鸿蒙开发(四)UIAbility和Page交互

    通过上一篇的学习,相信大家对UIAbility已经有了初步的认知。在上篇中,我们最后实现了一个小demo,从一个UIAbility调起了另外一个UIAbility。当时我提到过,暂不实现比如点击EntryAbility中的控件去触发跳转,而是在EntryAbility加载完后直接打开FuncUIAbility。本篇,带着大家一起学习下UIAbility和Page之间的交互。

鸿蒙系列的上一篇:​​​​​​​鸿蒙开发(三)探索UIAbility-CSDN博客文章浏览阅读526次,点赞9次,收藏9次。前文提到过,在使用DevEco创建鸿蒙项目的时候,会选择Empty Ability,那么这个Ability是什么呢?其实对比Android Studio创建Android项目时选择的Empty Activity,感觉Harmony的Ability更像是Android的Activity,但只能说像,不完全等同。本篇,我们就基于API9一起探索下Ability。因为本人是Android开发者,所以文章中会时不时的跟Android对比,如果你也是Android开发者 ,那么理解起来应该不难。https://blog.csdn.net/qq_21154101/article/details/135595700?spm=1001.2014.3001.5501

目录

一、温故而知新

二、UIAbility和Page交互

1、使用EventHub

2、globalThis

三、Demo效果展示


一、温故而知新

    在学习UIAbility和Page之间的交互之前,我们先回顾下已掌握的知识:

1、UIAbility是如何创建的?

2、Page是如何创建的?

3、UIAbility是如何跟Page绑定的?

4、UIAbility是如何跟另一个UIAbility交互的?

    如果以上四个问题你还不了解或者不是很清楚,可以参考下我的上一篇文章。如果都很清楚了,那么本篇跟着我一起实现这样一个demo。要求如下:

1、实现2个UIAbility,分别为EntryUIAbility和FuncUIAbility,对应有两个Page,分别为Index和Func。

2、Index页面里面有一个Hello Harmony的Text控件,为其增加点击事件,点击后传递一个内容为"Welcome to Harmony"的msg给与其绑定的EntryUIAbility。

3、EntryUIAbility收到点击事件后,调起FuncUIAbility。

4、FuncUIAbility将msg传递给与其绑定的Func页面。

5、Func页面接受到msg后,将其展现在该页面的一个Text控件中。

    好了,需求就是这样,是不是非常简单呢?接下来,我们一起手把手实现下!

二、UIAbility和Page交互

    在正式动手之前,我们先思考下如何实现?如果你做过Android,你该知道实现点击事件非常简单。抛开mvp和mvvm的架构,我们完全可以在Activity中对控件添加点击事件,然后调起另外一个Activity即可。在鸿蒙中,不能这么去做,因为UIAbility和Page其实是分离的。鸿蒙给我们提供了两种方式,来实现UIAbility组件与Page之间的交互。

  • 使用EventHub进行数据通信:基于发布订阅模式来实现,事件需要先订阅后发布,订阅者收到消息后进行处理。
  • 使用globalThis进行数据同步:ArkTS引擎实例内部的一个全局对象,在ArkTS引擎实例内部都能访问。

    EventHub是以Ability组件为中心,目前只发现它适用于将Ability作为事件的订阅者,而Page作为事件的发布者。也就是Page到Ability的单方通信。globalThis是一个全局的对象,不管是Ability或是Page均可以双向通信。准确来讲,不应该叫做通信,应该叫做读取。

1、使用EventHub

    EventHub提供了Ability组件(UIAbility和ExtensionAbility)的事件机制,以Ability组件为中心提供了订阅、取消订阅和触发事件的数据通信能力。这个其实就类似Android的EventBus,不过多介绍。

(1)既然要使用EventHub,那么首先就是获取一个EventHub实例。可以在EntryUIAbility的onCreate方法通过context去获取:

  onCreate(want, launchParam) {hilog.info(0x0000, this.tag, 'Ability onCreate');// 获取eventHublet eventhub = this.context.eventHub;...}

(2)接下来,在EntryUIAbility的onCreate中去注册EventHub,并在收到事件的时候调起FuncUIAbility,同时传递数据data:

onCreate(want, launchParam) {hilog.info(0x0000, this.tag, 'Ability onCreate');// 获取eventHublet eventhub = this.context.eventHub;// 执行订阅操作eventhub.on(this.event1, (...data) => {// 触发事件,完成相应的业务操作if (data != null && data.length > 0) {this.openFuncUiAbility(data[0]);}hilog.info(0x0000, this.tag, data.toString());});}

注意:data为可变参数,类型为数组,因此需要判空判断length然后按照数组的方式使用index获取参数。

(3)实现openFuncUiAbility()方法,接收参数message,并且在调起FuncUIAbility时把message作为want的info参数带过去:

  openFuncUiAbility(message) {let info = message// 调起app内其他的UIAbilitylet want: Want = {deviceId: '', // deviceId为空表示本设备bundleName: 'com.example.tuduharmonydemo', // 必填moduleName: '', // moduleName为空表示本模块abilityName: 'FuncAbility', // 必填parameters: { // 自定义信息info: info}}this.context.startAbility(want).then(() => {hilog.info(0x0000, this.tag, 'Succeeded in starting ability.');}).catch((err) => {hilog.error(0x0000, this.tag, `Failed to start ability. Code is ${err.code}, message is ${err.message}`);})}

注意:want的参数是一个json,可以塞多个参数,暂时用不到。

(4)在Index页面中实现onClick点击事件,调用eventHubFunc方法去触发事件:

@Entry
@Component
struct Index {@State message: string = 'Hello Harmony'private context = getContext(this) as common.UIAbilityContextbuild() {Row() {Column() {Text(this.message).fontSize(50).onClick(() => {this.eventHubFunc()})}.width('100%')}.height('100%')}

(5)实现eventHubFunc方法,在Page中通过eventHub.emit()触发事件,可以根据需要传入0或多个参数:

eventHubFunc() {// 不带参数触发自定义“event1”事件this.context.eventHub.emit('event1')// 带1个参数触发自定义“event1”事件this.context.eventHub.emit('event1', 'Welcome to Harmony')    // 在本次需求中,我们使用传递一个参数即可// 带2个参数触发自定义“event1”事件this.context.eventHub.emit('event1', 1, '222')// 开发者可以根据实际的业务场景设计事件传递的参数}

    上面提到过,eventHub传递的参数为可变参数,类型为数组,在这里贴一下emit的源码,可以看到为Object[]数组:

    /*** Trigger the event callbacks.* @param { string } event - Indicates the event.* @param { Object[] } args - Indicates the callback arguments.* @throws { BusinessError } 401 - If the input parameter is not valid parameter.* @syscap SystemCapability.Ability.AbilityRuntime.Core* @StageModelOnly* @since 9*/emit(event: string, ...args: Object[]): void;

    这样,已经实现了我们前面所列需求的第1-3个。第4-5个,我们需要借助上文提到的第二种方式globalThis实现。

2、globalThis

    globalThis是ArkTS引擎实例内部的一个全局对象,引擎内部的UIAbility/ExtensionAbility/Page都可以使用,因此可以使用globalThis全局对象进行数据同步。如下图:

    那么接下来,我们一起基于globalThis来实现第4-5个需求吧。

(1)在FuncUIAbility的onCreate中使用globalThis接收want里面的参数info:

  onCreate(want, launchParam) {let info = want?.parameters?.info;globalThis.entryAbilityInfo = info;hilog.info(0x0000, 'testTag', info);}

(2)在Func页面中,实现aboutToAppear,这是在调用build进行展现之前的函数,在这里通过globalThis获取参数,同时赋值给message,然后在build方法中展现message:

import hilog from '@ohos.hilog'
@Entry
@Component
struct Func {@State message: string = 'Func Page'aboutToAppear(){this.message = globalThis.entryAbilityInfohilog.info(0x0000, 'TTTT', this.message?? '');}build() {Row() {Column() {Text(this.message).fontSize(50)}.width('100%')}.height('100%')}
}

三、Demo效果展示

    至此,理论上我们已经一步步实现了篇首提出的需求:

1、实现2个UIAbility,分别为EntryUIAbility和FuncUIAbility,对应有两个Page,分别为Index和Func。

2、Index页面里面有一个Hello Harmony的Text控件,为其增加点击事件,点击后传递一个内容为"Welcome to Harmony"的msg给与其绑定的EntryUIAbility。

3、EntryUIAbility收到点击事件后,调起FuncUIAbility。

4、FuncUIAbility将msg传递给与其绑定的Func页面。

5、Func页面接受到msg后,将其展现在该页面的一个Text控件中。

    接下来,我们一起run一下我们的项目,看下效果是否符合预期:

​​​​​​​

    最后,简单总结一下。本篇我们一起回顾了之前学习的关于UIAbility的相关知识,并在开篇抛出了一个UIAbility和Page相互交互的需求。然后我们拆分需求,循序渐进地实现了我们的需求。并在最后,向大家展示了一下demo的效果。在文章中,有几处加了背景颜色的需要特别注意的信息,大家需要格外的留意,以防止掉进坑里。下一篇,跟大家一起学习下UI开发的基础知识。

相关文章:

鸿蒙开发(四)UIAbility和Page交互

通过上一篇的学习,相信大家对UIAbility已经有了初步的认知。在上篇中,我们最后实现了一个小demo,从一个UIAbility调起了另外一个UIAbility。当时我提到过,暂不实现比如点击EntryAbility中的控件去触发跳转,而是在Entry…...

K8s(七)四层代理Service

Service概述 Service在Kubernetes中提供了一种抽象的方式来公开应用程序的网络访问,并提供了负载均衡和服务发现等功能,使得应用程序在集群内外都能够可靠地进行访问。 每个Service都会自动关联一个对应的Endpoint。当创建一个Service时,Ku…...

鼎捷软件获评国家级智能制造“AAA级集成实施+AA级咨询设计”供应商

为贯彻落实《“十四五”智能制造发展规划》,健全智能制造系统解决方案供应商(以下简称“供应商”)分类分级体系,推动供应商规范有序发展,智能制造系统解决方案供应商联盟组织开展了供应商分类分级评定(第一批)工作,旨在遴选一批专…...

(循环依赖问题)学习spring的第九天

Bean实例的属性填充 Spring在属性注入时 , 分为如下几种情况 : 注入单向对象引用 : 如usersevice里注入userdao , userdao里没有注入其他属性 注入双向对象引用 : 如usersevice里注入userdao , userdao也注入usersevice属性 二 . 着重看循环依赖问题 (搞清原理即可) 问题提出…...

Kotlin的数据类

引言 我们在做项目中涉及到各种数据类的处理,很多很杂乱。难免一个人的知识点有盲点,所以想着做个整理。 定义 在平时的使用中,我们会用到一些类来保持一些数据或状态,我们习惯上成为bean或者entity,也有的定义为mod…...

PTA 7-13 统计工龄

给定公司N名员工的工龄,要求按工龄增序输出每个工龄段有多少员工。 输入格式: 输入首先给出正整数N(≤105),即员工总人数;随后给出N个整数,即每个员工的工龄,范围在[0, 50]。 输出格式: 按工…...

算法常用思路总结

思路 1. 求数组中最大最小值思路代码 2. 计算阶乘思路:代码: 3. 得到数字的每一位思路代码 4. 计算时间类型5. 最大公约数、最小公倍数6. 循环数组的思想题目:猴子选大王代码 补充经典例题1. 复试四则运算题目内容题解 2. 数列求和题目内容题…...

Leetcode 3016. Minimum Number of Pushes to Type Word II

Leetcode 3016. Minimum Number of Pushes to Type Word II 1. 解题思路2. 代码实现 题目链接:3016. Minimum Number of Pushes to Type Word II 1. 解题思路 这道题的话思路其实还是蛮简单的,显然我们的目的是要令对给定的word在键盘上敲击的次数最小…...

node.js如何将webp转jpg图片

在Node.js中,可以使用一些库来实现将WebP图像转换为JPEG。一个常用的库是sharp,它是一个快速、高效的图像处理库。以下是一个简单的Node.js脚本示例,演示如何使用sharp库将WebP转换为JPEG: 首先,确保已经安装了sharp库…...

达梦数据库 忘记 SYSDBA 密码 处理方法

DM 提供数据库身份验证模式、基于操作系统的身份验证模式、外部身份验证模式和 UKEY 身份验证模式来保护对数据库访问的安全。数据库身份验证模式需要利用数据库口令, 即在创建或修改用户时指定用户口令,用户在登录时输入对应口令进行身份验证;基于操作 …...

SpringBoot ES 重建 Mapping

SpringBoot ES 重建 Mapping 1 复制数据2 删除老索引3 重建索引4 复制回数据 1 复制数据 POST http://elastic:123456127.0.0.1:9200/_reindex{"source": {"index": "老索引名称"},"dest": {"index": "备份索引名称&q…...

【51单片机】矩阵按键

0、前言 参考&#xff1a;普中 51 单片机开发攻略 1、硬件 2、软件 main.c #include <reg52.h> #include <intrins.h> #include "delayms.h"typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; #define GPIO_KEY P1 #d…...

Redis- AOF刷盘策略

在Redis中&#xff0c;appendfsync everysec 是一个与持久化相关的配置选项&#xff0c;它属于 Redis 的 AOF&#xff08;Append Only File&#xff09;持久化策略的一部分。 Redis支持两种主要的数据持久化方式&#xff1a;RDB&#xff08;快照&#xff09;和AOF&#xff08;…...

标量、向量、矩阵和张量的区别?

标量、向量、矩阵和张量是数学和物理学中常用的概念&#xff0c;它们在多维数据表示和处理中扮演着关键角色。下面是这些概念的基本区别&#xff1a; 标量&#xff08;Scalar&#xff09;: -标量是单个数字&#xff0c;用于表示单一的量。 -它没有方向。 -在数学中&#xff0…...

【51单片机】动态数码管

0、前言 参考&#xff1a; 普中51单片机开发攻略–A2.pdf 1、数码管介绍 上一章我们主要是介绍一位数码管的内部结构及控制原理。下面我们再来介 绍下多位数码管及动态显示原理的相关知识。 1.1 多位数码管简介 2、74HC245 和 74HC138 芯片介绍 2.1 74HC245 芯片简介 2.2 7…...

Webpack5入门到原理22:提升打包构建速度

HotModuleReplacement 为什么 开发时我们修改了其中一个模块代码&#xff0c;Webpack 默认会将所有模块全部重新打包编译&#xff0c;速度很慢。 所以我们需要做到修改某个模块代码&#xff0c;就只有这个模块代码需要重新打包编译&#xff0c;其他模块不变&#xff0c;这样…...

EXCEL VBA获取幸运数字号码

EXCELVBA获取幸运数字号码 以下就是VBA幸运号码产生的程序&#xff0c;复制粘贴到VBA代码框即可运行 Option Base 1 Sub 幸运号码()Dim n As Integer, i As Integer, j As IntegerDim l() As Integern Application.InputBox("请输入需要产生幸运号码的数量&#xff1a;…...

【标准IO】fseek函数、ftell函数、fflush函数、getline函数

目录 fseekftellrewindfflushgetline 橙色 当你在文件中写入了10个字符后&#xff0c;又想把这10个字符读出来&#xff0c;该怎么做呢&#xff1f;因为有文件操作符指针的存在&#xff0c;此时该指针已经指在了这10个字符末尾&#xff0c;所以需要把该指针重定向&#xff0c;这…...

VSCODE使用CMAKE显示命令无法找到

背景&#xff1a;使用了code server&#xff0c;安装CMAKE和CMAKE TOOLS&#xff0c;但是通过ctrlshiftp打开命令面板&#xff0c;运行随便一个cmake指令&#xff0c;都出现了指令无法找到。具体为“命令"CMake: 配置"导致错误 (command ‘cmake.configure’ not fou…...

【SpringCloud】微服务框架后端部署详细过程记录20240119

前言&#xff1a;前两天公司接到客户提供的一个微服务框架&#xff0c;导师让我在本地部署验证一下该框架的可用性&#xff0c;借此机会记录一下微服务项目的一个基本部署流程&#xff0c;仅供学习参考&#xff0c;如有不足还请指正&#xff01; 文件结构 提供的压缩文件共包含…...

《设计模式的艺术》笔记 - 桥接模式

介绍 桥接模式将抽象部分与其实现部分分离&#xff0c;使它们都可以独立地变化。它是一种对象结构型模式&#xff0c;又称为柄体模式或接口模式 实现 myclass.h // // Created by yuwp on 2024/1/12. //#ifndef DESIGNPATTERNS_MYCLASS_H #define DESIGNPATTERNS_MYCLASS_H#…...

Redis高并发分布式锁

目录 场景描述 订单扣减场景举例 代码调整1 代码调整2 代码调整3 redisson锁续命核心代码 场景描述 订单扣减场景举例 //首先在redis中set stock 300 RequestMapping("/deduct_stock") public String deductStock() {int stock Integer.parseInt(stringRedi…...

组件开发遇到的问题(vue的问题)

组件的开发和引用 <template><div class"xx">组件</div> </template> <script>export default {name: viewMore,components: {},data() {return {}}} </script> <style scoped>可以定义组件都有的样式 </style> …...

vue3前端开发,感受一下组合式api和VUE2选项式的差异

vue3前端开发,感受一下组合式api和VUE2选项式的差异&#xff01;今天开始&#xff0c;正式开始&#xff0c;进入学习Vue3的内容。以后代码&#xff0c;案例分享&#xff0c;都会采用组合式api的模式为大家做展示。 今天是第一节&#xff0c;带大家感受一下&#xff0c;Vue3的组…...

电梯调度问题文献阅读

电梯调度问题文献阅读 文章目录 电梯调度问题文献阅读[toc]文献阅读1. 陈纪龙,孟洪兵,吴刚等.六层电梯模拟系统的研究与实现[J].伊犁师范学院学报(自然科学版),2014,8(01):57-62.2. 陈福兰,杜虹.浅析电梯并联运行的几种调度方法[J].装备制造技术,2012,(10):178-180190.3. 马春江…...

文心一言 VS 讯飞星火 VS chatgpt (183)-- 算法导论13.4 7题

七、用go语言&#xff0c;假设用 RB-INSERT 将一个结点 x 插入一棵红黑树&#xff0c;紧接着又用 RB-DELETE 将它从树中删除。结果的红黑树与初始的红黑树是否一样&#xff1f;证明你的答案。 文心一言&#xff1a; 首先&#xff0c;我们需要明确RB-INSERT和RB-DELETE的基本操…...

ChatGLM vs ChatGPT

所有的NLP大模型 都是transformer结构 1.Mask attention 的策略不同 2.训练任务目标不同 国内大模型nb公司&#xff1a;百度、清华智谱 一、主流大模型 粉色&#xff1a;Encoder-only。 绿色&#xff1a;Encoder-Decoder&#xff0c;尽头智谱ChatGLM。 蓝色&#xff1a;…...

leetcode热题100.三数之和

Problem: 15. 三数之和 文章目录 题目解题方法复杂度Code 题目 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元…...

GitLab服务器忘记root密码处理方式

GitLab服务器忘记root密码处理方式 文章目录 GitLab服务器忘记root密码处理方式1. Gitlab查看用户id号1. 通过api接口查询2. 在Linux终端里直接通过curl命令查询 2. 进入GitLab数据库中查询并修改root密码 1. Gitlab查看用户id号 1. 通过api接口查询 接口查询地址&#xff1a;…...

js-cookie的使用--token的数据实现持久化

1.下载 npm install js-cookie 2.引入 import Cookies from "js-cookie"; 3.使用 // 写入cookie Cookies.set(name, value) // 读取 Cookies.get(name) // > value Cookies.get(nothing) // > undefined // 读取所有可见的cookie Cookies.get() // 删除某项co…...