当前位置: 代码网 > it编程>编程语言>C/C++ > 鸿蒙开发(四)UIAbility和Page交互

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

2024年08月02日 C/C++ 我要评论
通过上一篇的学习,相信大家对UIAbility已经有了初步的认知。在上篇中,我们最后实现了一个小demo,从一个UIAbility调起了另外一个UIAbility。当时我提到过,暂不实现比如点击EntryAbility中的控件去触发跳转,而是在EntryAbility加载完后直接打开FuncUIAbility。本篇,带着大家一起学习下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之间的交互之前,我们先回顾下已掌握的知识:

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

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

二、uiability和page交互

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

    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());
    });
  }

(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}`);
    })
  }

(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效果展示

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

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

​​​​​​​

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

 最后,分享一款免费看热门电影和电视剧的app,仅限android:

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com