通过上一篇的学习,相信大家对uiability已经有了初步的认知。在上篇中,我们最后实现了一个小demo,从一个uiability调起了另外一个uiability。当时我提到过,暂不实现比如点击entryability中的控件去触发跳转,而是在entryability加载完后直接打开funcuiability。本篇,带着大家一起学习下uiability和page之间的交互。
目录
一、温故而知新
在学习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:
发表评论