|
HarmonyOSNEXT—应用通信之Emitter
序言
在应用开发过程中,我们对于应用中数据和响应事件的传递,都会选择不同的通信方式,在选择这些通信方式时,我们需要考虑不同通信方式下我们的实现逻辑,以及是否满足我们的需求,本文主要介绍,应用在同一进程的通信方式
一、基于同进程的通信方式——Emitter
简介:
Emitter提供在同一进程不同线程,或者同一进程同一线程的通信方式,在应用开发中通常被用作组件间,或者窗口间传递消息;注意如果跨线程传递数据,数据是会被自动序列化的
使用方式:
- // 单次订阅,收到回调后,自动取消订阅
- emitter.once({eventId: 1}, () => {
- console.info('once callback');
- });
- emitter.once("onceClick", () => {
- console.info('once onClick callback');
- });
复制代码- // 持续订阅事件,没有取消订阅就会一直接收消息
- emitter.on({eventId: 2}, () => {
- console.info('once callback');
- });
- emitter.on("Click", () => {
- console.info('on onClick callback');
- });
复制代码- let eventData: emitter.EventData = {
- data: {
- "once": "send",
- }
- };
- // 发送指定事件
- emitter.emit({eventId: 1}, eventData)
- emitter.emit("onceClick" , eventData)
- emitter.emit("onceClick" ,{ priority: emitter.EventPriority.HIGH }, eventData)
复制代码- // 取消事件的订阅
- emitter.off(2)
- emitter.off("Click")
- // 取消指定回调的事件订阅
- emitter.off(1, callback)
- emitter.off("onceClick", callback)
复制代码 二、项目示例:
使用Emitter来完成跨窗口传递消息,并在指定页面进行刷新,主要用于在同一进程下,不同的窗口或者不同上下文间传递消息- // index.ets
- import { emitter } from '@kit.BasicServicesKit';
- import { MyWindowManager } from '../util/windowManger';
- @Entry
- @Component
- struct Index {
- @State message: string = 'Hello World';
- aboutToAppear(): void {
- emitter.on('click', (data) => {
- let result = data.data
- this.message = result?.TestEmitter
- MyWindowManager.getInstance().closeDialog("testEmitterDialog")
- })
- }
- build() {
- Column({space: 20}) {
- Text(this.message).fontSize(50).fontWeight(FontWeight.Bold).margin({top: 50})
- Button("第一个弹框")
- .fontSize(50)
- .fontWeight(FontWeight.Bold)
- .onClick(() => {
- MyWindowManager.getInstance().showDialogView("testEmitterDialog", 0)
- })
- }
- .height('100%')
- .width('100%')
- }
- }
- // TestEmitter.ets
- import { emitter } from '@kit.BasicServicesKit';
- @Entry
- @Component
- struct TestEmitter {
- @State message: string = 'TestEmitter';
- build() {
- Column({space: 20}) {
- Text("这是一个弹框").fontSize(50)
- .fontWeight(FontWeight.Bold)
- Button("点击弹框发送消息")
- .fontSize(26)
- .fontWeight(FontWeight.Bold)
- .onClick(() => {
- emitter.emit('click', {
- data: {
- "TestEmitter": this.message
- }
- })
- })
- }
- .height('100%')
- .width('100%')
- }
- }
- // windowManger.ets
- import window from '@ohos.window';
- import { display } from '@kit.ArkUI';
- const TAG = "WindowManager"
- export class MyWindowManager {
- static getInstance(): MyWindowManager {
- if (globalThis.mWindowManager == null) {
- globalThis.mWindowManager = new MyWindowManager();
- }
- return globalThis.mWindowManager;
- }
- showDialogView(dialogName: string, offsetY: number) {
- console.log(TAG, "showDialogView")
- let dialogView = AppStorage.get(dialogName) as window.Window;
- if (dialogView) {
- console.log(TAG, "dialogView showWindow")
- dialogView.showWindow(() => {
- dialogView.setWindowFocusable(true);
- dialogView.setWindowTouchable(true);
- });
- } else {
- console.log(TAG, "dialogView is undefined ");
- this.createDialogWindow(dialogName, offsetY);
- }
- }
- closeDialog(dialogName: string) {
- try {
- let dialogView = AppStorage.get(dialogName) as window.Window
- if (!dialogView) {
- console.log(TAG, "dialogView is null")
- }
- dialogView.destroyWindow()
- AppStorage.set(dialogName, null)
- } catch (e) {
- console.error(TAG, 'close window err' + JSON.stringify(e))
- }
- }
- /**
- * 创建Dialog提示窗口
- */
- async createDialogWindow(dialogName: string, offsetY: number) {
- try {
- let config: window.Configuration = {
- ctx: globalThis.context,
- name: dialogName,
- windowType: window.WindowType.TYPE_DIALOG
- }
- let win = await window.createWindow(config)
- await win.setPreferredOrientation(window.Orientation.UNSPECIFIED);
- await win.setUIContent('pages/' + "TestEmitter")
- let dis = display.getDefaultDisplaySync()
- console.log(TAG, "dis.height: " + dis.height)
- await win.resize(dis.width -100, 300)
- await win.moveWindowTo(50, dis.height - vp2px(300) - vp2px(offsetY))
- await win.showWindow()
- win.setWindowBackgroundColor('#33000000')
- win.setWindowFocusable(true)
- win.setWindowTouchable(true)
- AppStorage.setOrCreate(dialogName, win)
- } catch (e) {
- console.error(TAG, 'createDialogWindow err = ' + JSON.stringify(e))
- }
- }
- }
复制代码 |
|