鸿蒙NEXT实践(二):公共事件通信实践-智能节电案例

在鸿蒙操作系统中,公共事件通信是一种强大的进程间通信(IPC)机制,允许应用动态订阅和发布事件。本文将以一个智能节电应用为例,展示如何使用公共事件通信机制来实现应用间的动态交互。

公共事件分类

公共事件从系统角度可分为:系统公共事件自定义公共事件

  • 系统公共事件:CES内部定义的公共事件,当前仅支持系统应用和系统服务发布,例如HAP安装、更新、卸载等公共事件。目前支持的系统公共事件请参见系统公共事件列表。

  • 自定义公共事件:应用定义的公共事件,可用于实现跨进程的事件通信能力。 公共事件按发送方式可分为:无序公共事件、有序公共事件和粘性公共事件。

  • 无序公共事件:CES在转发公共事件时,不考虑订阅者是否接收到该事件,也不保证订阅者接收到该事件的顺序与其订阅顺序一致。

  • 有序公共事件:CES在转发公共事件时,根据订阅者设置的优先级等级,优先将公共事件发送给优先级较高的订阅者,等待其成功接收该公共事件之后再将事件发送给优先级较低的订阅者。如果有多个订阅者具有相同的优先级,则他们将随机接收到公共事件。

  • 粘性公共事件:能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。普通的公共事件只能在订阅后发送才能收到,而粘性公共事件的特殊性就是可以先发送后订阅,同时也支持先订阅后发送。发送粘性事件必须是系统应用或系统服务,粘性事件发送后会一直存在系统中,且发送者需要申请ohos.permission.COMMONEVENT_STICKY权限,配置方式请参见声明权限。 运作机制

每个应用都可以按需订阅公共事件,订阅成功,当公共事件发布时,系统会将其发送给对应的应用。这些公共事件可能来自系统、其他应用和应用自身。

动态订阅公共事件

导入模块

首先,我们需要导入必要的模块:

ts 复制代码
// 导入基础服务Kit和性能分析Kit中的相关模块
import { BusinessError, commonEventManager } from '@ohos.BasicServicesKit';
import { hilog } from '@ohos.PerformanceAnalysisKit';
// 定义日志标签和域编号,用于日志输出
const TAG: string = 'PowerSavingApp';
const DOMAIN_NUMBER: number = 0xFF00;

创建订阅者信息

创建订阅者信息:

ts 复制代码
// 定义订阅者信息,指定需要订阅的事件列表
let subscriber: commonEventManager.CommonEventSubscriber | null = null;
let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
  events: ['device.battery.low'], // 订阅电量低事件
};

创建订阅者

创建订阅者,并保存返回的订阅者对象,用于后续的订阅、退订等操作:

ts 复制代码
// 创建订阅者对象
commonEventManager.createSubscriber(subscribeInfo, (err: BusinessError, data: commonEventManager.CommonEventSubscriber) => {
  if (err) {
    // 如果创建订阅者失败,输出错误日志
    hilog.error(DOMAIN_NUMBER, TAG, `Failed to create subscriber. Code is ${err.code}, message is ${err.message}`);
    return;
  }
  // 如果创建成功,保存订阅者对象并输出日志
  hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in creating subscriber.');
  subscriber = data;
});

订阅公共事件

创建订阅回调函数,订阅回调函数会在接收到事件时触发:

ts 复制代码
// 订阅公共事件
if (subscriber !== null) {
  commonEventManager.subscribe(subscriber, (err: BusinessError, data: commonEventManager.CommonEventData) => {
    if (err) {
      // 如果订阅失败,输出错误日志
      hilog.error(DOMAIN_NUMBER, TAG, `Failed to subscribe common event. Code is ${err.code}, message is ${err.message}`);
      return;
    }
    // 如果成功接收到事件,执行降低功耗的操作
    handleLowBatteryEvent(data);
  });
} else {
  hilog.error(DOMAIN_NUMBER, TAG, `Need to create subscriber`);
}

// 处理电量低事件
function handleLowBatteryEvent(data: commonEventManager.CommonEventData) {
  // 根据接收到的事件数据执行降低功耗的逻辑
  hilog.info(DOMAIN_NUMBER, TAG, `Received low battery event. Taking power saving measures.`);
  // 这里可以添加降低功耗的具体操作,例如关闭后台任务、降低屏幕亮度等
}

取消订阅

调用unsubscribe()方法取消订阅某事件:

ts 复制代码
// 取消订阅公共事件
if (subscriber !== null) {
  commonEventManager.unsubscribe(subscriber, (err: BusinessError) => {
    if (err) {
      // 如果取消订阅失败,输出错误日志
      hilog.error(DOMAIN_NUMBER, TAG, `UnsubscribeCallBack err = ${JSON.stringify(err)}`);
    } else {
      // 如果取消订阅成功,输出日志并释放订阅者对象
      hilog.info(DOMAIN_NUMBER, TAG, `Unsubscribe success`);
      subscriber = null;
    }
  });
}

公共事件发布

在某些情况下,我们的应用可能需要发布一些自定义事件,例如在用户手动触发节电模式时。

ts 复制代码
// 构建需要发布的公共事件信息
let options: commonEventManager.CommonEventPublishData = {
  code: 1,
  data: 'Manual power saving triggered',
};

// 发布自定义的节电模式触发事件
commonEventManager.publish('app.power.save.trigger', options, (err: BusinessError) => {
  if (err) {
    // 如果发布事件失败,输出错误日志
    hilog.error(DOMAIN_NUMBER, TAG, 'PublishCallBack err = ' + JSON.stringify(err));
  } else {
    // 如果发布成功,输出日志
    hilog.info(DOMAIN_NUMBER, TAG, 'Publish success');
  }
});

至此,就完成了一个智能节电应用的核心逻辑,包括订阅电量低事件、处理事件、发布自定义事件和取消订阅。 关于公共事件通信机制的其他信息,例如类型定义等等,大家可参考华为官网公共事件服务了解更多。

下面是完整的demo代码,供大家参考理解公共事件通信。

完整代码

ts 复制代码
// 导入模块
import { BusinessError, commonEventManager } from '@ohos.BasicServicesKit';
import { hilog } from '@ohos.PerformanceAnalysisKit';
const TAG: string = 'PowerSavingApp';
const DOMAIN_NUMBER: number = 0xFF00;

// 创建订阅者信息
let subscriber: commonEventManager.CommonEventSubscriber | null = null;
let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
  events: ['device.battery.low'], // 订阅电量低事件
};

// 创建订阅者对象
commonEventManager.createSubscriber(subscribeInfo, (err: BusinessError, data: commonEventManager.CommonEventSubscriber) => {
  if (err) {
    hilog.error(DOMAIN_NUMBER, TAG, `Failed to create subscriber. Code is ${err.code}, message is ${err.message}`);
    return;
  }
  hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in creating subscriber.');
  subscriber = data;
});

// 订阅公共事件
if (subscriber !== null) {
  commonEventManager.subscribe(subscriber, (err: BusinessError, data: commonEventManager.CommonEventData) => {
    if (err) {
      hilog.error(DOMAIN_NUMBER, TAG, `Failed to subscribe common event. Code is ${err.code}, message is ${err.message}`);
      return;
    }
    handleLowBatteryEvent(data);
  });
} else {
  hilog.error(DOMAIN_NUMBER, TAG, `Need to create subscriber`);
}

// 处理电量低事件
function handleLowBatteryEvent(data: commonEventManager.CommonEventData) {
  hilog.info(DOMAIN_NUMBER, TAG, `Received low battery event. Taking power saving measures.`);
  // 这里可以添加降低功耗的具体操作,例如关闭后台任务、降低屏幕亮度等
}

// 发布自定义的节电模式触发事件
let options: commonEventManager.CommonEventPublishData = {
  code: 1,
  data: 'Manual power saving triggered',
};

commonEventManager.publish('app.power.save.trigger', options, (err: BusinessError) => {
  if (err) {
    hilog.error(DOMAIN_NUMBER, TAG, 'PublishCallBack err = ' + JSON.stringify(err));
  } else {
    hilog.info(DOMAIN_NUMBER, TAG, 'Publish success');
  }
});

// 取消订阅公共事件
if (subscriber !== null) {
  commonEventManager.unsubscribe(subscriber, (err: BusinessError) => {
    if (err) {
      hilog.error(DOMAIN_NUMBER, TAG, `UnsubscribeCallBack err = ${JSON.stringify(err)}`);
    } else {
      hilog.info(DOMAIN_NUMBER, TAG, `Unsubscribe success`);
      subscriber = null;
    }
  });
}
相关推荐
CL_IN1 小时前
企业数据集成:实现高效调拨出库自动化
java·前端·自动化
月未央2 小时前
HarmonyOS Next 开发系列:Local 状态管理实践
harmonyos
浪九天3 小时前
Vue 不同大版本与 Node.js 版本匹配的详细参数
前端·vue.js·node.js
qianmoQ3 小时前
第五章:工程化实践 - 第三节 - Tailwind CSS 大型项目最佳实践
前端·css
椰果uu3 小时前
前端八股万文总结——JS+ES6
前端·javascript·es6
微wx笑4 小时前
chrome扩展程序如何实现国际化
前端·chrome
~废弃回忆 �༄4 小时前
CSS中伪类选择器
前端·javascript·css·css中伪类选择器
CUIYD_19894 小时前
Chrome 浏览器(版本号49之后)‌解决跨域问题
前端·chrome
IT、木易4 小时前
跟着AI学vue第五章
前端·javascript·vue.js
薛定谔的猫-菜鸟程序员4 小时前
Vue 2全屏滚动动画实战:结合fullpage-vue与animate.css打造炫酷H5页面
前端·css·vue.js