当前位置: 首页 > news >正文

鸿蒙NEXT实战:使用公共事件实现跨进程通信

在鸿蒙应用开发中,巧妙使用公共事件机制,能让跨进程通信变得轻松高效。

在鸿蒙应用开发中,进程间通信(IPC)是一个常见需求。HarmonyOS NEXT 提供了多种IPC机制,其中公共事件(Common Event)因其简单易用且支持一对多通信模式,成为许多场景下的理想选择。

公共事件机制概述

公共事件是HarmonyOS中的一种发布-订阅模式的通信机制,适用于跨进程、跨应用的事件通知场景。它基于消息中心机制,允许一个进程发布事件,多个进程订阅并接收该事件。

公共事件的特点:

  • 跨进程通信:能够在不同进程间传递事件

  • 一对多通信:一个事件可以被多个订阅者接收

  • 异步执行:事件发布后立即返回,不会阻塞发布者线程

  • 松耦合:发布者和订阅者不需要知道彼此的存在

公共事件的工作原理

公共事件机制涉及三个核心角色:

  1. 发布者:负责创建并发布公共事件

  2. 订阅者:注册对特定事件的兴趣,并定义回调处理函数

  3. 公共事件管理器:系统组件,负责管理事件的分发

当发布者发布一个事件时,公共事件管理器会根据事件的类型和权限,将事件传递给所有匹配的订阅者。

实战:使用公共事件实现跨进程通信

下面通过一个完整示例,演示如何在鸿蒙NEXT中使用公共事件进行跨进程通信。

1. 创建事件订阅者

首先,我们需要在接收方进程中创建事件订阅者:

typescript

import commonEventManager from '@ohos.commonEventManager';
import Base from '@ohos.base';// 订阅公共事件
function subscribeCommonEvent() {const subscribeInfo = {events: ["com.example.demo.MY_EVENT"]  // 要订阅的事件类型};// 创建订阅者commonEventManager.createSubscriber(subscribeInfo, (err: Base.BusinessError, subscriber: commonEventManager.CommonEventSubscriber) => {if (err) {console.error(`Failed to create subscriber. Code is ${err.code}, message is ${err.message}`);return;}console.info('Succeeded in creating subscriber.');// 订阅事件if (subscriber !== null) {commonEventManager.subscribe(subscriber, (err: Base.BusinessError, data: commonEventManager.CommonEventData) => {if (err) {console.error(`Failed to subscribe common event. Code is ${err.code}, message is ${err.message}`);return;}console.info('Subscribe success, received event data:' + JSON.stringify(data));// 处理接收到的事件数据handleReceivedEvent(data);});} else {console.error(`Need create subscriber`);}});
}// 处理接收到的事件
function handleReceivedEvent(eventData: commonEventManager.CommonEventData) {const receivedData = eventData.data;const code = eventData.code;console.info(`Received event, code: ${code}, data: ${JSON.stringify(receivedData)}`);// 根据事件数据更新UI或执行其他操作// ...
}

2. 发布公共事件

在发送方进程中,创建并发布公共事件:

typescript

import commonEventManager from '@ohos.commonEventManager';
import Base from '@ohos.base';// 发布公共事件
function publishCommonEvent() {const options: commonEventManager.CommonEventPublishData = {code: 1,  // 事件代码data: "This is event data",  // 事件数据bundleName: "com.example.publisher"  // 可选:发布者包名};// 发布公共事件commonEventManager.publish("com.example.demo.MY_EVENT", options, (err: Base.BusinessError) => {if (err) {console.error('[CommonEvent] PublishCallBack err=' + JSON.stringify(err));} else {console.info('[CommonEvent] Publish success');}});
}// 发布带复杂数据的事件
function publishComplexEvent() {const complexData = {message: "Hello from another process!",timestamp: new Date().getTime(),count: 42};const options: commonEventManager.CommonEventPublishData = {code: 1001,data: JSON.stringify(complexData)  // 复杂数据需要序列化};commonEventManager.publish("com.example.demo.COMPLEX_EVENT", options, (err: Base.BusinessError) => {if (err) {console.error('Failed to publish complex event: ' + JSON.stringify(err));} else {console.info('Complex event published successfully');}});
}

3. 在Ability中集成公共事件

在EntryAbility中订阅公共事件:

typescript

import UIAbility from '@ohos.app.ability.UIAbility';
import commonEventManager from '@ohos.commonEventManager';
import window from '@ohos.window';
import Base from '@ohos.base';export default class EntryAbility extends UIAbility {private subscriber: commonEventManager.CommonEventSubscriber | null = null;onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {console.info('EntryAbility onCreate');this.subscribeToEvents();}private subscribeToEvents(): void {const subscribeInfo = {events: ["com.example.demo.MY_EVENT"]};commonEventManager.createSubscriber(subscribeInfo, (err: Base.BusinessError, subscriber: commonEventManager.CommonEventSubscriber) => {if (err) {console.error(`Failed to create subscriber in Ability. Code is ${err.code}, message is ${err.message}`);return;}this.subscriber = subscriber;console.info('Succeeded in creating subscriber in Ability.');if (this.subscriber !== null) {commonEventManager.subscribe(this.subscriber, (err: Base.BusinessError, data: commonEventManager.CommonEventData) => {if (err) {console.error(`Failed to subscribe common event in Ability. Code is ${err.code}, message is ${err.message}`);return;}console.info('Ability received event data: ' + JSON.stringify(data));});}});}onDestroy(): void {// 取消订阅if (this.subscriber !== null) {commonEventManager.unsubscribe(this.subscriber, (err: Base.BusinessError) => {if (err) {console.error(`Failed to unsubscribe common event. Code is ${err.code}, message is ${err.message}`);return;}console.info('Succeeded in unsubscribing common event.');});}super.onDestroy();}
}

4. 在UI页面中发布事件

在SubPage.ets页面中发布事件:

typescript

@Entry
@Component
struct SubPage {@State message: string = 'Hello World';build() {Column() {Text(this.message).fontSize(20).margin(10)Button('发布简单事件').onClick(() => {this.publishSimpleEvent();}).margin(10)Button('发布复杂事件').onClick(() => {this.publishComplexEvent();}).margin(10)}.width('100%').height('100%')}private publishSimpleEvent() {let options: commonEventManager.CommonEventPublishData = {code: 1,data: "initial data",};commonEventManager.publish("selfPublishEvent", options, (err: Base.BusinessError) => {if (err) {console.error('[CommonEvent] PublishCallBack err=' + JSON.stringify(err));} else {console.info('[CommonEvent] Publish success');this.message = '事件发布成功!';}});}private publishComplexEvent() {const eventData = {action: 'USER_ACTION',userId: '12345',screen: 'MainPage',timestamp: new Date().toISOString()};let options: commonEventManager.CommonEventPublishData = {code: 200,data: JSON.stringify(eventData),};commonEventManager.publish("com.example.demo.USER_ACTION_EVENT", options, (err: Base.BusinessError) => {if (err) {console.error('Failed to publish user action event: ' + JSON.stringify(err));this.message = '事件发布失败';} else {console.info('User action event published successfully');this.message = '用户动作事件已发布';}});}
}

公共事件的进阶用法

1. 使用有序公共事件

有序公共事件允许订阅者按照优先级处理事件,并可以终止事件的传播:

typescript

// 发布有序公共事件
function publishOrderedEvent() {const options: commonEventManager.CommonEventPublishData = {code: 1,data: "Ordered event data",isOrdered: true  // 设置为有序事件};commonEventManager.publish("com.example.demo.ORDERED_EVENT", options, (err: Base.BusinessError) => {if (err) {console.error('Failed to publish ordered event: ' + JSON.stringify(err));} else {console.info('Ordered event published successfully');}});
}

2. 使用粘性公共事件

粘性事件会在发布后保留在系统中,新的订阅者仍然可以收到之前发布的事件:

typescript

// 发布粘性公共事件
function publishStickyEvent() {const options: commonEventManager.CommonEventPublishData = {code: 1,data: "Sticky event data",isSticky: true  // 设置为粘性事件};commonEventManager.publish("com.example.demo.STICKY_EVENT", options, (err: Base.BusinessError) => {if (err) {console.error('Failed to publish sticky event: ' + JSON.stringify(err));} else {console.info('Sticky event published successfully');}});
}

3. 订阅系统公共事件

除了自定义事件,还可以订阅系统预定义的公共事件:

typescript

// 订阅系统事件:屏幕点亮
function subscribeSystemEvent() {const subscribeInfo = {events: [commonEvent.SCREEN_ON]  // 系统预定义事件};commonEventManager.createSubscriber(subscribeInfo, (err: Base.BusinessError, subscriber: commonEventManager.CommonEventSubscriber) => {if (err) {console.error(`Failed to create system event subscriber. Code is ${err.code}, message is ${err.message}`);return;}if (subscriber !== null) {commonEventManager.subscribe(subscriber, (err: Base.BusinessError, data: commonEventManager.CommonEventData) => {if (err) {console.error(`Failed to subscribe system event. Code is ${err.code}, message is ${err.message}`);return;}console.info('Screen turned on');// 处理屏幕点亮事件});}});
}

开发注意事项

  1. 权限管理:某些系统事件需要相应的权限才能订阅,确保在module.json5中声明所需权限。

  2. 性能考虑:避免在事件回调中执行耗时操作,以免影响系统性能。

  3. 内存管理:及时取消不再需要的事件订阅,防止内存泄漏。

  4. 数据大小:事件数据不宜过大,建议控制在KB级别。

  5. 错误处理:始终处理发布和订阅操作的可能错误,提高应用稳定性。

与其他通信方式的对比

虽然公共事件功能强大,但鸿蒙NEXT还提供了其他进程间通信方式,可根据具体场景选择:

  • Emitter:用于同一进程内的线程间通信

  • Binder:用于跨进程通信,支持同步和异步调用

  • 共享内存:通过共享内存区域实现高效数据传输

与这些机制相比,公共事件更适合一对多、异步、松耦合的通信场景。

总结

公共事件机制是鸿蒙NEXT中实现跨进程通信的强大工具,通过简单的发布-订阅模式,可以轻松实现进程间的解耦通信。本文介绍了公共事件的基本用法和进阶特性,希望能帮助你在实际开发中更好地利用这一机制。

掌握公共事件的使用,将为构建复杂、高效的鸿蒙应用奠定坚实基础。

http://www.dtcms.com/a/462266.html

相关文章:

  • npm升级提示error engine not compatible with your version of node/npm: npm@11.6.2
  • 我的网站为什么打不开怎么回事啊携程做旅游的网站
  • 网站推广的表现方式网站开发需要用到哪些设备
  • 缓存大杀器-redis
  • 网站建设管理方案网站开发与app开发的区别
  • 装修公司网站制作大数据营销成功案例
  • 【STM32】I2C通信—硬件外设
  • 脚手架学习
  • 做网站好还是做淘宝好现在手机网站用什么做的
  • 建设行业网站平台的瓶颈网站网页
  • 【Linux】线程概念与控制(2)
  • vue项目发布后图标乱码解决方案
  • 成都手机网站重庆本地建站
  • UI设计(二)赛博科技修仙通讯录——东方仙盟筑基期
  • 实时数仓历史数据优化
  • 网站建设在哪能看企业网站建立流程的第一步是什么
  • 告别手动配置:用 Terraform 定义你的 RustFS 存储帝国
  • 36.Linux Shell编程
  • AI智能体赋能社会科学研究领域之仿真:心智疆域的重塑与伦理韧性机制的建立
  • daily notes[81]
  • 常用命令和tricks
  • 【AI编程前沿】人类编写代码 vs AI生成代码:质量、漏洞与复杂度的大规模比较研究
  • 黑龙江建设人力资源网站网站建设及安全制度
  • 广州市增城建设局网站怎样开发一个app软件
  • 机器视觉Halcon3D中add_deformable_surface_model_reference_point的作用
  • 设计一个简单的旅游网站全网拓客app
  • 从零到一构建高可用微服务架构的核心实践与挑战
  • 【深入浅出PyTorch】--4.PyTorch基础实战
  • 项目源码安全审查怎么写
  • 陕西网站建设哪家专业培训班有哪些