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

news2024/11/27 19:35:26

    通过上一篇的学习,相信大家对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');
    // 获取eventHub
    let eventhub = this.context.eventHub;
    ...
  }

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

onCreate(want, launchParam) {
    hilog.info(0x0000, this.tag, 'Ability onCreate');
    // 获取eventHub
    let 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内其他的UIAbility
    let 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.UIAbilityContext

  build() {
    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.entryAbilityInfo
    hilog.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的效果。在文章中,有几处加了背景颜色的需要特别注意的信息,大家需要格外的留意,以防止掉进坑里。

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

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

相关文章

Qt编程之仿gnome-terminal终端样式 +颜色文字显示

Qt仿linux 终端样式 颜色文字 1.说再多废话不如直接show code2.实现效果 本文采用QTextBrowser作为文本显示窗口,进行文本的显示。本文实例实现的效果并没有终端的输入效果,这里只是提供一些仿终端样式思路。 1.说再多废话不如直接show code 1.ui文件…

Openwrt 下动态路由协议(quagga-OSPF)配置与验证

文章目录 前言网络拓扑静态路由方式动态路由方式Openwrt下 Quagga 安装Quagga 配置R1路由器zebra配置R1路由器ospf配置R2路由器zebra配置R2路由器ospf配置OSPF协议分析REF本文将在两台openwrt系统上安装配置quagga, 搭建一套完整环境,来验证OSPF动态路由的基本功能和实际效果,…

关于变量在多个.C文件中使用(Undefined symbol tempbuff (referred from main.o).问题解决)

1、如图结构,想在multimenu.C和usart1.c中使用变量tempbuff 于是,就将使用的代码移动了过来,为SetTxData1_toLCD(0x00,0x01);和UserUart1Send( tempbuff1,sizeof(tempbuff1));,编译后提示错误如下: communication_prot…

从零开始学习Python基础语法:打开编程大门的钥匙

文章目录 一、引言1.1 Python作为一种流行的编程语言的介绍1.2 Python的应用领域和适用性 二、为什么选择Python2.1 Python的简洁性和易读性2.2 Python的跨平台特性 三、Python在数据科学和人工智能领域的应用3.1 第一个Python程序3.1.1 Hello, World!:编写并运行你…

XXL-Job的搭建接入Springboot项目(详细)

一、XXL-Job介绍 XXL-Job 是一款开源的分布式任务调度平台,由 Xuxueli(徐雪里)开发。它基于 Java 技术栈,提供了一套简单易用、高可靠性的任务调度解决方案。 XXL-Job 的主要作用是帮助开发者实现定时任务的调度和执行。它可以用…

安装脚手架Vue CLI详解!!!

Vue CLI基本介绍: Vue CLI是Vue官方提供的一个全局命令工具。可以帮助我们快速创建一个开发Vue项目的标准化基础架子【集成了webpack配置】 安装脚手架好处: 开箱即用,零配置;内置babel等工具;标准化 安装步骤&#…

vscode中关于python的一些常用配置

文章目录 python cv2 提示配置第一步 配置提示信息第二部 重启vs 可能还不行,那就重新安装以下opencv-python 配置pytest还是如上,将下入的位置打开编写测试用例 配置跨文件import在工作目录中新建一个.env文件输入内容如下打开.vscode中的setting.json …

react umi/max 封装页签组件

1. models/tabs // 全局共享数据示例 import { useState } from react;const useUser () > {const [items, setItems] useState<any[]>([]); // 页签的全局Item数据const [key, setKey] useState<string>(/home); // 页签的高亮Keyreturn {items,setItems…

leetcode热题100.路径总和 III

Problem: 437. 路径总和 III 文章目录 题目思路1复杂度1Code1思路2复杂度2Code2 题目 给定一个二叉树的根节点 root &#xff0c;和一个整数 targetSum &#xff0c;求该二叉树里节点值之和等于 targetSum 的 路径 的数目。 路径 不需要从根节点开始&#xff0c;也不需要在叶…

Leetcode:128. 最长连续序列

128. 最长连续序列 乍一看感觉很简单&#xff0c;一看要用O(n)??? 因为我觉得题目很难而且题目看起来很简单&#xff0c;感觉以后会用到&#x1f606;&#xff0c;做个记录 1.朴素做法 思路 答:任何一段连续的数都有一个左端点&#xff1a;比如&#xff08;1&#xff0c;…

TCP 拥塞控制对数据延迟的影响

哈喽大家好&#xff0c;我是咸鱼 今天分享一篇文章&#xff0c;是关于 TCP 拥塞控制对数据延迟产生的影响的。作者在服务延迟变高之后进行抓包分析&#xff0c;结果发现时间花在了 TCP 本身的机制上面&#xff1a;客户端并不是将请求一股脑发送给服务端&#xff0c;而是只发送…

web架构师编辑器内容-编辑器组件图层面板功能开发01-锁定隐藏功能的开发

我们这一部分主要是对最右侧图层面板功能进行剖析&#xff0c;完成对应的功能的开发: 每个图层都对应编辑器上面的元素&#xff0c;有多少个元素就对应多少个图层&#xff0c;主要的功能如下&#xff1a; 锁定功能&#xff1a;点击锁定&#xff0c;在编辑器中没法编辑对应的组…

git 常规操作及设置

git 常规操作及设置 Git是一个分布式版本控制系统&#xff0c;可以用来跟踪文件的修改历史并与其他人进行协作开发。下面是一些常见的Git操作及设置&#xff1a; 初始化仓库&#xff1a;使用命令git init在当前目录创建一个新的Git仓库。 克隆仓库&#xff1a;使用命令git clo…

web terminal - 如何在mac os上运行gotty

gotty可以让你使用web terminal的方式与环境进行交互&#xff0c;实现终端效果 假设你已经配置好了go环境&#xff0c;首先使用go get github.com/yudai/gotty命令获取可执行文件&#xff0c;默认会安装在$GOPATH/bin这个目录下&#xff0c;注意如果你的go版本比较高&#xff…

C++设计模式(李建忠)笔记3

C设计模式&#xff08;李建忠&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 参考链接 Youtube: C设计模式 Gtihub源码与PPT&#xff1a;https://github.com/ZachL1/Bilibili-plus 豆瓣: 设计模式–可复用面向对象软件的基础 文章目录 C设计模…

线性代数的学习和整理23:用EXCEL计算 向量/向量组的点乘 (内积) (建设ing)

目录 前言&#xff1a;EXCEL里的的向量相关计算公式 0.1 EXCEL里相关公式 0.2 先说结论&#xff1a;向量组的点乘公式和 向量组的点乘公式不一样 1 向量的点乘 (内积) 1.1 向量的点乘公式 1.2 EXCEL里向量点乘的计算 ​编辑 1.3 向量点乘的性质 1.3.1 内积的公式…

docker环境下mongo副本集的部署及异常修复

最近更换了办公地点。部署在本地docker环境里的mongo数据库不能使用了。原因是本地的ip地址变更。以前的mongo副本集的配置需要更新。处理完后&#xff0c;索性重新记录一下mongo副本集在docker中的部署流程。 mongo的事务及副本集 我们先了解一下什么是事务&#xff0c;事务…

LangChain新发布v0.1.0稳定版本有哪些新功能?

▼最近直播超级多&#xff0c;预约保你有收获 今晚直播&#xff1a;《LangChain 框架案例实战》 —1— 首个稳定版本 LangChain v0.1.0 LangChain v0.1.0 发布后&#xff0c;就不仅仅是一个开发框架了&#xff0c;而是一个开发者平台&#xff08;LLMOps&#xff09;&#xff0c…

css-盒子等样式学习

盒子居中&#xff0c;继承外层盒子的宽高 兼容性&#xff08;border-box&#xff09;将边框收到盒子内部 初始化div 不用管box-setting content-box 还原 创建为一个类 &#xff0c;让所有需要还原的类 进行继承 padding 用法表示margin上下左右边距 body 外边距&…

Python ❀ 使用代码实现API接口调用详解

文章目录 1. 工具准备1.1. requests代码包1.2. BurpSuite抓包工具 2. 操作过程2.1. 一个简单的请求2.1.1. Burp获取响应2.1.2. 转发获取响应 2.2. 构造GET类型URL参数2.3. 构造请求头部2.4. 构造POST类型payload数据 本文主要讲解常用API接口如何使用python实现。 API&#xff…