查看: 98|回复: 0

HarmonyOSNEXT—应用通信之Emitter

[复制链接]

1

主题

2

回帖

15

积分

新手上路

积分
15
发表于 2025-4-3 15:12:20 | 显示全部楼层 |阅读模式
HarmonyOSNEXT—应用通信之Emitter

序言

在应用开发过程中,我们对于应用中数据和响应事件的传递,都会选择不同的通信方式,在选择这些通信方式时,我们需要考虑不同通信方式下我们的实现逻辑,以及是否满足我们的需求,本文主要介绍,应用在同一进程的通信方式
一、基于同进程的通信方式——Emitter

简介:

Emitter提供在同一进程不同线程,或者同一进程同一线程的通信方式,在应用开发中通常被用作组件间,或者窗口间传递消息;注意如果跨线程传递数据,数据是会被自动序列化的
使用方式:
  1.     // 单次订阅,收到回调后,自动取消订阅
  2.     emitter.once({eventId: 1}, () => {
  3.       console.info('once callback');
  4.     });
  5.     emitter.once("onceClick", () => {
  6.       console.info('once onClick callback');
  7.     });
复制代码
  1.     // 持续订阅事件,没有取消订阅就会一直接收消息
  2.     emitter.on({eventId: 2}, () => {
  3.       console.info('once callback');
  4.     });
  5.     emitter.on("Click", () => {
  6.       console.info('on onClick callback');
  7.     });
复制代码
  1.     let eventData: emitter.EventData = {
  2.       data: {
  3.         "once": "send",
  4.       }
  5.     };
  6.     // 发送指定事件
  7.     emitter.emit({eventId: 1}, eventData)
  8.     emitter.emit("onceClick" , eventData)
  9.     emitter.emit("onceClick" ,{ priority: emitter.EventPriority.HIGH }, eventData)
复制代码
  1.     // 取消事件的订阅
  2.     emitter.off(2)
  3.     emitter.off("Click")
  4.     // 取消指定回调的事件订阅
  5.     emitter.off(1, callback)
  6.     emitter.off("onceClick", callback)
复制代码
二、项目示例:

使用Emitter来完成跨窗口传递消息,并在指定页面进行刷新,主要用于在同一进程下,不同的窗口或者不同上下文间传递消息
  1. // index.ets
  2. import { emitter } from '@kit.BasicServicesKit';
  3. import { MyWindowManager } from '../util/windowManger';
  4. @Entry
  5. @Component
  6. struct Index {
  7.   @State message: string = 'Hello World';
  8.   aboutToAppear(): void {
  9.     emitter.on('click', (data) => {
  10.       let result = data.data
  11.       this.message = result?.TestEmitter
  12.       MyWindowManager.getInstance().closeDialog("testEmitterDialog")
  13.     })
  14.   }
  15.   build() {
  16.     Column({space: 20}) {
  17.       Text(this.message).fontSize(50).fontWeight(FontWeight.Bold).margin({top: 50})
  18.       Button("第一个弹框")
  19.         .fontSize(50)
  20.         .fontWeight(FontWeight.Bold)
  21.         .onClick(() => {
  22.           MyWindowManager.getInstance().showDialogView("testEmitterDialog", 0)
  23.         })
  24.     }
  25.     .height('100%')
  26.     .width('100%')
  27.   }
  28. }
  29. // TestEmitter.ets
  30. import { emitter } from '@kit.BasicServicesKit';
  31. @Entry
  32. @Component
  33. struct TestEmitter {
  34.   @State message: string = 'TestEmitter';
  35.   build() {
  36.     Column({space: 20}) {
  37.       Text("这是一个弹框").fontSize(50)
  38.         .fontWeight(FontWeight.Bold)
  39.       Button("点击弹框发送消息")
  40.         .fontSize(26)
  41.         .fontWeight(FontWeight.Bold)
  42.         .onClick(() => {
  43.           emitter.emit('click', {
  44.             data: {
  45.               "TestEmitter": this.message
  46.             }
  47.           })
  48.         })
  49.     }
  50.     .height('100%')
  51.     .width('100%')
  52.   }
  53. }
  54. // windowManger.ets
  55. import window from '@ohos.window';
  56. import { display } from '@kit.ArkUI';
  57. const TAG = "WindowManager"
  58. export class MyWindowManager {
  59.   static getInstance(): MyWindowManager {
  60.     if (globalThis.mWindowManager == null) {
  61.       globalThis.mWindowManager = new MyWindowManager();
  62.     }
  63.     return globalThis.mWindowManager;
  64.   }
  65.   showDialogView(dialogName: string, offsetY: number) {
  66.     console.log(TAG, "showDialogView")
  67.     let dialogView = AppStorage.get(dialogName) as window.Window;
  68.     if (dialogView) {
  69.       console.log(TAG, "dialogView  showWindow")
  70.       dialogView.showWindow(() => {
  71.         dialogView.setWindowFocusable(true);
  72.         dialogView.setWindowTouchable(true);
  73.       });
  74.     } else {
  75.       console.log(TAG, "dialogView is undefined ");
  76.       this.createDialogWindow(dialogName, offsetY);
  77.     }
  78.   }
  79.   closeDialog(dialogName: string) {
  80.     try {
  81.       let dialogView = AppStorage.get(dialogName) as window.Window
  82.       if (!dialogView) {
  83.         console.log(TAG, "dialogView is null")
  84.       }
  85.       dialogView.destroyWindow()
  86.       AppStorage.set(dialogName, null)
  87.     } catch (e) {
  88.       console.error(TAG, 'close window err' + JSON.stringify(e))
  89.     }
  90.   }
  91.   /**
  92.    * 创建Dialog提示窗口
  93.    */
  94.   async createDialogWindow(dialogName: string, offsetY: number) {
  95.     try {
  96.       let config: window.Configuration = {
  97.         ctx: globalThis.context,
  98.         name: dialogName,
  99.         windowType: window.WindowType.TYPE_DIALOG
  100.       }
  101.       let win = await window.createWindow(config)
  102.       await win.setPreferredOrientation(window.Orientation.UNSPECIFIED);
  103.       await win.setUIContent('pages/' + "TestEmitter")
  104.       let dis = display.getDefaultDisplaySync()
  105.       console.log(TAG, "dis.height: " + dis.height)
  106.       await win.resize(dis.width -100, 300)
  107.       await win.moveWindowTo(50, dis.height - vp2px(300) - vp2px(offsetY))
  108.       await win.showWindow()
  109.       win.setWindowBackgroundColor('#33000000')
  110.       win.setWindowFocusable(true)
  111.       win.setWindowTouchable(true)
  112.       AppStorage.setOrCreate(dialogName, win)
  113.     } catch (e) {
  114.       console.error(TAG, 'createDialogWindow err = ' + JSON.stringify(e))
  115.     }
  116.   }
  117. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表