鸿蒙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;
    }
  });
}
相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
youyin1 天前
HarmonyOS ArkUI 组件与自定义组件零基础:从搭页面到组件化开发
华为·harmonyos
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大1 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师1 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端