鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

07-19 1246阅读

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

import common from ‘@ohos.app.ability.common’;

@Entry

@Component

struct Index {

private context = getContext(this) as common.UIAbilityContext;

startAbilityTest() {

let want = {

// Want参数信息

};

this.context.startAbility(want);

}

// 页面展示

build() {

// …

}

}

5.UIAbility组件与UI的数据同步

主要有两种方式:

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

1、注册事件,使用其中一种即可

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) {

// 获取eventHub

let eventhub = this.context.eventHub;

// 执行订阅操作

eventhub.on(‘event1’, this.func1);

eventhub.on(‘event1’, (…data) => {

// 触发事件,完成相应的业务操作

console.info(TAG, '2. ’ + JSON.stringify(data));

});

}

}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

2、触发事件

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() {

// …

}

}

3、取消事件

// context为UIAbility实例的AbilityContext

this.context.eventHub.off(‘event1’);

🦋5.2 使用globalThis进行数据同步

在HarmonyOS中,globalThis是一个全局对象,它提供了一个统一的方式来访问不同环境下的全局对象。在HarmonyOS中,globalThis可以用来访问当前运行环境中的全局对象,可以是浏览器环境中的window对象,也可以是Node.js环境中的global对象。

使用globalThis可以方便地在不同环境下编写通用的代码,不需要针对不同的环境做特殊的处理。例如,可以使用globalThis来访问全局的console对象,无论在浏览器环境还是Node.js环境中,都可以使用console.log()来输出日志。

虽然globalThis提供了一种通用的访问全局对象的方式,但在实际编程中还是建议根据具体的环境来使用相应的全局对象。

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

☀️5.2.1 UIAbility和Page之间使用globalThis

1、注册

import UIAbility from ‘@ohos.app.ability.UIAbility’

export default class EntryAbility extends UIAbility {

onCreate(want, launch) {

globalThis.entryAbilityWant = want;

// …

}

// …

}

2、获取

let entryAbilityWant;

@Entry

@Component

struct Index {

aboutToAppear() {

entryAbilityWant = globalThis.entryAbilityWant;

}

// 页面展示

build() {

// …

}

}

☀️5.2.2 UIAbility和UIAbility之间使用globalThis

1、注册

import UIAbility from ‘@ohos.app.ability.UIAbility’

export default class AbilityA extends UIAbility {

onCreate(want, launch) {

globalThis.entryAbilityStr = ‘AbilityA’; // AbilityA存放字符串“AbilityA”到globalThis

// …

}

}

2、获取

import UIAbility from ‘@ohos.app.ability.UIAbility’

export default class AbilityB extends UIAbility {

onCreate(want, launch) {

// AbilityB从globalThis读取name并输出

console.info('name from entryAbilityStr: ’ + globalThis.entryAbilityStr);

// …

}

}

☀️5.2.3 globalThis使用的注意事项

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

案例:

1、在AbilityA文件中使用globalThis中存放了UIAbilityContext。

import UIAbility from ‘@ohos.app.ability.UIAbility’

export default class AbilityA extends UIAbility {

onCreate(want, launch) {

globalThis.context = this.context; // AbilityA存放context到globalThis

// …

}

}

2、在AbilityA的页面中获取该UIAbilityContext并进行使用。使用完成后将AbilityA实例切换至后台。

@Entry

@Component

struct Index {

onPageShow() {

let ctx = globalThis.context; // 页面中从globalThis中取出context并使用

let permissions = [‘com.example.permission’]

ctx.requestPermissionsFromUser(permissions,(result) => {

// …

});

}

// 页面展示

build() {

// …

}

}

3、在AbilityB文件中使用globalThis中存放了UIAbilityContext,并且命名为相同的名称。

import UIAbility from ‘@ohos.app.ability.UIAbility’

export default class AbilityB extends UIAbility {

onCreate(want, launch) {

// AbilityB覆盖了AbilityA在globalThis中存放的context

globalThis.context = this.context;

// …

}

}

4、在AbilityB的页面中获取该UIAbilityContext并进行使用。此时获取到的globalThis.context已经表示为AbilityB中赋值的UIAbilityContext内容。

@Entry

@Component

struct Index {

onPageShow() {

let ctx = globalThis.context; // Page中从globalThis中取出context并使用

let permissions = [‘com.example.permission’]

ctx.requestPermissionsFromUser(permissions,(result) => {

console.info(‘requestPermissionsFromUser result:’ + JSON.stringify(result));

});

}

// 页面展示

build() {

// …

}

}

5、在AbilityB实例切换至后台,将AbilityA实例从后台切换回到前台。此时AbilityA的onCreate生命周期不会再次进入。

import UIAbility from ‘@ohos.app.ability.UIAbility’

export default class AbilityA extends UIAbility {

onCreate(want, launch) { // AbilityA从后台进入前台,不会再走这个生命周期

globalThis.context = this.context;

// …

}

}

6、在AbilityA的页面再次回到前台时,其获取到的globalThis.context表示的为AbilityB的UIAbilityContext,而不是AbilityA的UIAbilityContext,在AbilityA的页面中使用则会出错。

@Entry

@Component

struct Index {

onPageShow() {

let ctx = globalThis.context; // 这时候globalThis中的context是AbilityB的context

let permissions=[‘com.example.permission’];

ctx.requestPermissionsFromUser(permissions,(result) => { // 使用这个对象就会导致进程崩溃

console.info(‘requestPermissionsFromUser result:’ + JSON.stringify(result));

});

}

// 页面展示

build() {

// …

}

}

6.UIAbility组件间交互(设备内)

🦋6.1 启动应用内的UIAbility

1、启动方

let wantInfo = {

deviceId: ‘’, // deviceId为空表示本设备

bundleName: ‘com.example.myapplication’,

abilityName: ‘FuncAbility’,

moduleName: ‘module1’, // moduleName非必选

parameters: { // 自定义信息

info: ‘来自EntryAbility Index页面’,

},

}

// context为调用方UIAbility的AbilityContext

this.context.startAbility(wantInfo).then(() => {

// …

}).catch((err) => {

// …

})

2、接受方

import UIAbility from ‘@ohos.app.ability.UIAbility’;

import Window from ‘@ohos.window’;

export default class FuncAbility extends UIAbility {

onCreate(want, launchParam) {

// 接收调用方UIAbility传过来的参数

let funcAbilityWant = want;

let info = funcAbilityWant?.parameters?.info;

// …

}

}

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

// context为需要停止的UIAbility实例的AbilityContext

this.context.terminateSelf((err) => {

// …

});

🦋6.2 启动应用内的UIAbility并获取返回结果

1、启动方

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) => {

// …

})

2、接受方

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) => {

// …

});

3、获取接受方回调参数

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) => {

// …

})

🦋6.3 启动其他应用的UIAbility

1、接受方配置信息

{

“module”: {

“abilities”: [

{

// …

“skills”: [

{

“entities”: [

// …

“entity.system.default”

],

“actions”: [

// …

“ohos.want.action.viewData”

]

}

]

}

]

}

}

2、启动方

let wantInfo = {

deviceId: ‘’, // deviceId为空表示本设备

// 如果希望隐式仅在特定的捆绑包中进行查询,请取消下面的注释。

// bundleName: ‘com.example.myapplication’,

action: ‘ohos.want.action.viewData’,

// entities可以被省略。

entities: [‘entity.system.default’],

}

// context为调用方UIAbility的AbilityContext

this.context.startAbility(wantInfo).then(() => {

// …

}).catch((err) => {

// …

})

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

完成后不要忘了,停止

// context为需要停止的UIAbility实例的AbilityContext

this.context.terminateSelf((err) => {

// …

});

🦋6.4 启动其他应用的UIAbility并获取返回结果

1、接受方配置信息

{

“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) => {

// …

})

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) => {

// …

});

3、接收参数

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) => {

// …

})

🦋6.5 启动UIAbility的指定页面
☀️6.5.1 调用方UIAbility指定启动页面

let wantInfo = {

deviceId: ‘’, // deviceId为空表示本设备

bundleName: ‘com.example.myapplication’,

abilityName: ‘FuncAbility’,

moduleName: ‘module1’, // moduleName非必选

parameters: { // 自定义参数传递页面信息

router: ‘funcA’,

},

}

// context为调用方UIAbility的AbilityContext

this.context.startAbility(wantInfo).then(() => {

// …

}).catch((err) => {

// …

})

☀️6.5.2 目标UIAbility首次启动

import UIAbility from ‘@ohos.app.ability.UIAbility’

import Window from ‘@ohos.window’

export default class FuncAbility extends UIAbility {

funcAbilityWant;

onCreate(want, launchParam) {

// 接收调用方UIAbility传过来的参数

this.funcAbilityWant = want;

}

onWindowStageCreate(windowStage: Window.WindowStage) {

// Main window is created, set main page for this ability

let url = ‘pages/Index’;

if (this.funcAbilityWant?.parameters?.router) {

if (this.funcAbilityWant.parameters.router === ‘funA’) {

url = ‘pages/Second’;

}

}

windowStage.loadContent(url, (err, data) => {

// …

});

}

}

☀️6.5.3 目标UIAbility非首次启动

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

1、接收方

UIAbility实例之前已经创建完成,此时会进入UIAbility的onNewWant()回调中且不会进入onCreate()和onWindowStageCreate()生命周期回调

import UIAbility from ‘@ohos.app.ability.UIAbility’

export default class FuncAbility extends UIAbility {

onNewWant(want, launchParam) {

// 接收调用方UIAbility传过来的参数

globalThis.funcAbilityWant = want;

// …

}

}

2、更新页面UI

FuncAbility对应的Index页面是处于激活状态,不会重新变量声明以及进入aboutToAppear()生命周期回调中。因此可以在Index页面的onPageShow()生命周期回调中实现页面路由跳转的功能。

import router from ‘@ohos.router’;

@Entry

@Component

struct Index {

onPageShow() {

let funcAbilityWant = globalThis.funcAbilityWant;

let url2 = funcAbilityWant?.parameters?.router;

if (url2 && url2 === ‘funcA’) {

router.replaceUrl({

url: ‘pages/Second’,

})

}

}

// 页面展示

build() {

// …

}

}

🦋6.6 通过Call调用实现UIAbility交互(仅对系统应用开放)
☀️6.6.1 接口说明

Call调用是UIAbility能力的一种扩展,它允许UIAbility能力被外部调用,并进行通信。Call调用支持前台和后台两种启动方式,使得UIAbility能够在前台展示UI或者在后台创建并运行。通过Call调用,调用方和被调用方之间建立了IPC通信,应用开发者可以利用Call调用实现不同UIAbility之间的数据共享。

Call调用的核心接口是startAbilityByCall方法,与startAbility接口相比,startAbilityByCall具有以下不同之处:

  1. startAbilityByCall支持前台和后台两种启动方式,而startAbility仅支持前台启动。
  2. 调用方可以使用startAbilityByCall返回的Caller对象与被调用方进行通信,而startAbility没有通信能力。

Call调用的使用场景主要包括:

  1. 需要与被启动的UIAbility进行通信。
  2. 希望被启动的UIAbility在后台运行。
名词描述
CallerAbility进行Call调用的UIAbility(调用方)。
CalleeAbility被Call调用的UIAbility(被调用方)。
Caller实际对象,由startAbilityByCall接口返回,CallerAbility可使用Caller与CalleeAbility进行通信。
Callee实际对象,被CalleeAbility持有,可与Caller进行通信。

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

☀️6.6.2 开发步骤(创建Callee被调用端)

1、配置Ability的启动模式

“abilities”:[{

“name”: “.CalleeAbility”,

“srcEntrance”: “./ets/CalleeAbility/CalleeAbility.ts”,

“launchType”: “singleton”,

“description”: “ s t r i n g : C a l l e e A b i l i t y d e s c " , " i c o n " : " string:CalleeAbility_desc", "icon": " string:CalleeAbilityd​esc","icon":"media:icon”,

“label”: “$string:CalleeAbility_label”,

“visible”: true

}]

2、导入模块

import Ability from ‘@ohos.app.ability.UIAbility’;

3、定义约束

export default class MyParcelable {

num: number = 0

str: string = “”

constructor(num, string) {

this.num = num

this.str = string

}

marshalling(messageSequence) {

messageSequence.writeInt(this.num)

messageSequence.writeString(this.str)

return true

}

unmarshalling(messageSequence) {

this.num = messageSequence.readInt()

this.str = messageSequence.readString()

return true

}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

sible": true

}]

2、导入模块

import Ability from ‘@ohos.app.ability.UIAbility’;

3、定义约束

export default class MyParcelable {

num: number = 0

str: string = “”

constructor(num, string) {

this.num = num

this.str = string

}

marshalling(messageSequence) {

messageSequence.writeInt(this.num)

messageSequence.writeString(this.str)

return true

}

unmarshalling(messageSequence) {

this.num = messageSequence.readInt()

this.str = messageSequence.readString()

return true

}

[外链图片转存中…(img-preUHce2-1715515489270)]

[外链图片转存中…(img-vOXFWhGI-1715515489271)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]