#跟着晓明学鸿蒙# 鸿蒙系统开发高级教程 - 事件通知机制实战指南
引言
事件通知是现代操作系统中不可或缺的一部分,它使得系统组件、应用程序可以及时响应系统状态变化和用户交互。鸿蒙系统作为一款面向全场景的分布式操作系统,拥有一套完整而强大的事件通知机制,不仅支持本地事件处理,还能实现跨设备的事件分发和处理。本文将深入剖析鸿蒙系统的事件通知机制,包括架构设计、核心概念、使用方法以及最佳实践,帮助开发者全面理解并灵活运用这一重要功能。
事件通知机制概述
设计理念
鸿蒙系统的事件通知机制设计基于以下核心理念:
- 松耦合:发布者和订阅者之间无直接依赖关系,降低系统组件间的耦合度
- 异步处理:事件处理通常采用异步方式,避免阻塞主线程
- 分层架构:从系统级到应用级的多层次事件分发机制
- 分布式能力:支持跨设备的事件通知,实现多设备协同
- 性能优先:高效的事件分发与处理,最小化资源消耗
架构概览
鸿蒙系统的事件通知机制主要由以下几个部分组成:
- EventHandler(事件处理器):负责接收和处理特定类型的事件
- EventRunner(事件运行器):为EventHandler提供事件循环,管理事件队列
- InnerEvent(内部事件):系统内部事件的基本单元
- CommonEvent(公共事件):面向应用的通用事件机制
- Notification(通知):面向用户的系统通知服务
系统级事件处理机制
EventHandler与EventRunner
鸿蒙系统中,EventHandler与EventRunner构成了事件处理的基础设施。
EventRunner
EventRunner负责提供一个事件循环,用于管理事件队列并按顺序分发事件:
// 创建EventRunner示例
import { EventRunner } from '@ohos.events';
// 创建一个EventRunner实例
let runner = new EventRunner("ExampleRunner");
// 获取当前线程的EventRunner
let currentRunner = EventRunner.current();
// 获取主线程的EventRunner
let mainRunner = EventRunner.getMainEventRunner();
EventRunner的主要功能:
- 管理事件队列,按优先级和时间顺序处理事件
- 提供事件循环,支持同步和异步事件处理
- 支持优先级调度,确保高优先级事件优先处理
EventHandler
EventHandler负责实际处理事件,它必须关联到一个EventRunner:
// 创建EventHandler示例
import { EventHandler, EventRunner } from '@ohos.events';
class MyEventHandler extends EventHandler {
// 处理事件的回调函数
processEvent(event) {
console.log(`处理事件: ${event.eventId}`);
// 根据事件ID和数据进行处理
if (event.eventId === 1) {
// 处理事件1的逻辑
const data = event.data;
// ...处理数据
}
}
}
// 创建EventRunner
let runner = new EventRunner("MyRunner");
// 创建EventHandler并关联到runner
let handler = new MyEventHandler(runner);
// 发送事件
handler.sendEvent({
eventId: 1,
priority: EventHandler.Priority.IMMEDIATE,
data: { key: "value" }
});
// 延迟发送事件
handler.sendTimingEvent({
eventId: 2,
data: { message: "延迟消息" }
}, 1000); // 1000毫秒后发送
EventHandler的核心功能:
- 发送同步和异步事件
- 处理事件回调
- 支持延时事件和定时事件
- 可以设置事件优先级
InnerEvent详解
InnerEvent是鸿蒙系统内部事件的基本单元,具有以下特性:
// InnerEvent结构
interface InnerEvent {
eventId: number; // 事件ID
priority?: number; // 事件优先级
taskExecuteTime?: number; // 任务执行时间(用于延时事件)
data?: any; // 事件附带数据
}
InnerEvent可以携带不同类型的数据:
- 基本数据类型(数字、字符串、布尔值)
- 复杂对象(JSON对象、数组)
- 二进制数据(ArrayBuffer)
事件优先级
鸿蒙系统支持多级事件优先级,确保重要事件能够及时处理:
// 事件优先级常量
const Priority = {
IMMEDIATE: 0, // 立即优先级,最高
HIGH: 1, // 高优先级
NORMAL: 2, // 普通优先级(默认)
LOW: 3, // 低优先级
IDLE: 4 // 空闲优先级,最低
};
当事件队列中存在多个事件时,高优先级事件将优先被处理。
应用级事件机制
CommonEvent(公共事件)
CommonEvent是鸿蒙系统的公共事件机制,用于应用间的事件通信:
// 使用CommonEvent的示例
import commonEvent from '@ohos.commonEvent';
// 发布公共事件
function publishEvent() {
let options = {
code: 1, // 事件代码
data: "事件数据", // 事件数据
isOrdered: true, // 是否有序发送
isSticky: false // 是否为粘性事件
};
commonEvent.publish("com.example.MY_EVENT", options, (err) => {
if (err) {
console.error(`发布事件失败: ${err.message}`);
return;
}
console.log('事件发布成功');
});
}
// 订阅公共事件
function subscribeEvent() {
let subscribeInfo = {
events: ["com.example.MY_EVENT"], // 要订阅的事件列表
publisherPermission: "", // 发布者需要的权限
userData: "额外数据" // 用户数据
};
commonEvent.createSubscriber(subscribeInfo, (err, subscriber) => {
if (err) {
console.error(`创建订阅者失败: ${err.message}`);
return;
}
// 设置事件回调
commonEvent.subscribe(subscriber, (err, data) => {
if (err) {
console.error(`订阅事件失败: ${err.message}`);
return;
}
console.log(`收到事件: ${data.event}`);
console.log(`事件数据: ${data.data}`);
console.log(`事件代码: ${data.code}`);
// 处理事件...
});
});
}
CommonEvent的主要特性:
- 系统预定义事件:系统提供大量预定义事件,如启动完成、包安装/卸载、网络变化等
- 自定义事件:应用可以定义和发布自己的事件
- 有序事件:控制事件按特定顺序交付给订阅者
- 粘性事件:新订阅者可以接收到订阅前最近发布的事件
系统预定义事件
鸿蒙系统提供了丰富的预定义事件,以下是常用的系统事件:
// 系统事件常量部分示例
const CommonEventAction = {
ACTION_BOOT_COMPLETED: "ohos.action.BOOT_COMPLETED", // 系统启动完成
ACTION_PACKAGE_ADDED: "ohos.action.PACKAGE_ADDED", // 安装应用
ACTION_PACKAGE_REMOVED: "ohos.action.PACKAGE_REMOVED", // 卸载应用
ACTION_BATTERY_CHANGED: "ohos.action.BATTERY_CHANGED", // 电池状态变化
ACTION_CONNECTIVITY_CHANGE: "ohos.action.CONNECTIVITY_CHANGE", // 网络连接变化
ACTION_SCREEN_ON: "ohos.action.SCREEN_ON", // 屏幕点亮
ACTION_SCREEN_OFF: "ohos.action.SCREEN_OFF", // 屏幕关闭
ACTION_TIME_CHANGED: "ohos.action.TIME_CHANGED", // 系统时间变化
ACTION_LOCALE_CHANGED: "ohos.action.LOCALE_CHANGED", // 系统语言变化
// ...更多系统事件
};
Notification(通知)
鸿蒙系统的通知服务用于应用向用户展示重要信息:
// 使用通知服务的示例
import notification from '@ohos.notification';
// 创建并发送一个基本通知
function sendBasicNotification() {
// 创建通知内容
let contentBasic = {
title: "新消息提醒", // 通知标题
text: "您有一条新消息,请查看", // 通知内容
additionalText: "聊天应用" // 附加文本
};
// 创建通知请求
let request = {
content: contentBasic, // 通知内容
id: 1, // 通知ID
slotType: notification.SlotType.SOCIAL_COMMUNICATION, // 通知类型
deliveryTime: new Date().getTime() // 投递时间
};
// 发布通知
notification.publish(request, (err) => {
if (err) {
console.error(`发布通知失败: ${err.message}`);
return;
}
console.log('通知发送成功');
});
}
// 创建并发送一个带按钮的高级通知
function sendAdvancedNotification() {
// 创建通知内容
let contentAdvanced = {
title: "会议提醒",
text: "产品讨论会将在10分钟后开始",
additionalText: "会议室A",
briefText: "会议提醒", // 简短文本(通知折叠时显示)
expandedTitle: "产品讨论会议提醒", // 展开标题
longText: "产品迭代讨论会将在10分钟后于会议室A开始,请准时参加。会议内容包括:1. 产品功能评审 2. 迭代计划确认 3. 任务分配" // 长文本内容
};
// 创建按钮动作
let actionButton1 = {
title: "参加",
wantAgent: { // 点击按钮触发的意图
pkgName: "com.example.meeting",
abilityName: "com.example.meeting.JoinActivity"
}
};
let actionButton2 = {
title: "稍后提醒",
wantAgent: {
pkgName: "com.example.meeting",
abilityName: "com.example.meeting.RemindLaterActivity"
}
};
// 创建通知请求
let request = {
content: contentAdvanced,
id: 2,
slotType: notification.SlotType.CONTENT_INFORMATION,
actionButtons: [actionButton1, actionButton2], // 添加按钮
// 点击通知时触发的意图
wantAgent: {
pkgName: "com.example.meeting",
abilityName: "com.example.meeting.MeetingDetailActivity"
}
};
// 发布通知
notification.publish(request);
}
通知系统的主要功能:
- 通知渠道:按不同类别管理通知,用户可以针对不同渠道设置偏好
- 富文本通知:支持文本格式化、图片、按钮等富媒体内容
- 通知行为:可以为通知设置点击行为、按钮行为等
- 通知优先级:设置通知的重要程度,影响展示方式
- 通知分组:将相关通知归为一组,改善用户体验
分布式事件通知
鸿蒙系统最具特色的能力之一是支持分布式事件通知,实现跨设备的事件分发和处理。
分布式公共事件
分布式公共事件允许一个设备上的应用发布事件,由同一帐户下其他设备上的应用接收处理:
// 分布式公共事件示例
import commonEvent from '@ohos.commonEvent';
import distributedKVStore from '@ohos.data.distributedKVStore';
// 发布分布式事件
function publishDistributedEvent() {
// 创建分布式事件选项
let options = {
code: 1,
data: "分布式事件数据",
isOrdered: true,
isDistributed: true, // 标记为分布式事件
distributedDeviceId: [ // 目标设备列表
"device1234",
"device5678"
]
};
// 发布事件
commonEvent.publish("com.example.DISTRIBUTED_EVENT", options, (err) => {
if (err) {
console.error(`发布分布式事件失败: ${err.message}`);
return;
}
console.log('分布式事件发布成功');
});
}
// 订阅分布式事件
function subscribeDistributedEvent() {
let subscribeInfo = {
events: ["com.example.DISTRIBUTED_EVENT"],
distributedOptions: {
isDistributed: true, // 接收分布式事件
isSupportDistributed: true // 支持分布式事件处理
}
};
commonEvent.createSubscriber(subscribeInfo, (err, subscriber) => {
if (err) {
console.error(`创建分布式事件订阅者失败: ${err.message}`);
return;
}
commonEvent.subscribe(subscriber, (err, data) => {
if (err) {
console.error(`订阅分布式事件失败: ${err.message}`);
return;
}
console.log(`收到分布式事件: ${data.event}`);
console.log(`事件来源设备: ${data.sourceDeviceId}`);
console.log(`事件数据: ${data.data}`);
// 处理分布式事件...
});
});
}
分布式公共事件的关键特性:
- 跨设备分发:事件可以从源设备分发到目标设备
- 设备过滤:可以指定接收事件的目标设备
- 安全机制:只有受信任设备且同一帐户下的设备才能接收分布式事件
- 自动重试:在设备暂时不可用时支持重试机制
分布式通知
分布式通知允许在多个设备间同步和处理通知:
// 分布式通知示例
import notification from '@ohos.notification';
// 启用分布式通知
function enableDistributedNotification() {
notification.enableDistributed(true, (err) => {
if (err) {
console.error(`启用分布式通知失败: ${err.message}`);
return;
}
console.log('分布式通知已启用');
});
}
// 设置分布式通知设备
function setDistributedDevices() {
// 获取已连接的可信设备列表
let deviceList = []; // 应从设备管理器获取
notification.setDistributedDevices(deviceList, (err) => {
if (err) {
console.error(`设置分布式通知设备失败: ${err.message}`);
return;
}
console.log('分布式通知设备设置成功');
});
}
// 发布分布式通知
function publishDistributedNotification() {
let contentBasic = {
title: "新消息",
text: "您有一条新消息"
};
let request = {
content: contentBasic,
id: 100,
isDistributed: true, // 标记为分布式通知
distributedOption: {
deviceList: ["device1234", "device5678"], // 指定设备列表
syncOption: notification.DistributedSyncOption.ALL_DEVICES // 同步策略
}
};
notification.publish(request, (err) => {
if (err) {
console.error(`发布分布式通知失败: ${err.message}`);
return;
}
console.log('分布式通知发送成功');
});
}
// 监听来自其他设备的通知
function listenDistributedNotifications() {
let listener = {
onDistributedNotificationReceived: (data) => {
console.log(`收到来自设备 ${data.deviceId} 的通知`);
console.log(`通知ID: ${data.request.id}`);
console.log(`通知标题: ${data.request.content.title}`);
console.log(`通知内容: ${data.request.content.text}`);
// 处理来自其他设备的通知...
}
};
notification.addDistributedNotificationListener(listener);
}
分布式通知的主要功能:
- 多设备同步:通知可以在用户的多个设备间同步
- 智能分发:根据用户当前使用的设备智能决策通知展示
- 通知状态同步:一个设备上的通知状态变化(如已读、已处理)可以同步到其他设备
- 权限控制:用户可以控制哪些通知可以跨设备分发
事件总线(EventHub)
除了系统提供的事件机制外,鸿蒙还提供了轻量级的事件总线模式,用于应用内组件间通信:
// 事件总线示例
import eventHub from '@ohos.events.emitter';
// 定义事件ID
const EVENT_ID = 1001;
// 发布事件
function emitEvent() {
let eventData = {
data: {
message: "Hello EventHub!",
timestamp: new Date().getTime()
}
};
eventHub.emit(EVENT_ID, eventData);
console.log('事件已发布');
}
// 订阅事件
function subscribeToEventHub() {
let callback = (eventData) => {
console.log(`接收到事件: ${EVENT_ID}`);
console.log(`事件数据: ${JSON.stringify(eventData.data)}`);
// 处理事件数据...
};
// 创建事件订阅者
let subscription = {
eventId: EVENT_ID,
priority: eventHub.EventPriority.HIGH // 设置优先级
};
// 注册事件监听
let listenerId = eventHub.on(subscription, callback);
console.log(`事件监听器注册成功,ID: ${listenerId}`);
// 保存listenerId用于后续取消订阅
return listenerId;
}
// 取消事件订阅
function unsubscribeFromEventHub(listenerId) {
eventHub.off(listenerId);
console.log(`事件监听器 ${listenerId} 已移除`);
}
EventHub的主要特点:
- 轻量级:简单易用,适合应用内通信
- 高性能:事件分发效率高,资源占用少
- 支持优先级:可以设置事件处理的优先级
- 支持粘性事件:新订阅者可以收到之前发送的粘性事件
事件通知最佳实践
选择合适的事件机制
根据不同场景选择最合适的事件机制:
- EventHandler:适用于应用内部线程间通信,特别是UI线程与工作线程之间
- CommonEvent:适用于应用间通信,或者系统级事件的接收
- Notification:适用于需要用户关注的重要信息展示
- EventHub:适用于应用内部组件之间的轻量通信
优化事件处理性能
提高事件处理效率的最佳实践:
- 避免重复订阅:确保不会多次订阅同一事件
- 及时取消订阅:在组件生命周期结束时取消事件订阅
- 减少事件发送频率:对于高频事件,考虑使用节流或防抖技术
- 精简事件数据:只传递必要的数据,避免大对象
- 设置合理的优先级:为重要事件设置更高的优先级
// 示例:在组件生命周期中管理事件订阅
import commonEvent from '@ohos.commonEvent';
@Component
struct EventDemoComponent {
private subscriber = null;
private listenerId = -1;
aboutToAppear() {
// 创建订阅者
let subscribeInfo = {
events: ["com.example.MY_EVENT"]
};
commonEvent.createSubscriber(subscribeInfo, (err, subscriber) => {
if (err) {
console.error(`创建订阅者失败: ${err.message}`);
return;
}
this.subscriber = subscriber;
// 订阅事件
commonEvent.subscribe(this.subscriber, (err, data) => {
if (err) {
console.error(`订阅事件失败: ${err.message}`);
return;
}
// 处理事件...
console.log(`收到事件: ${data.event}`);
});
});
// 订阅事件总线
this.listenerId = eventHub.on({
eventId: 1001
}, (data) => {
// 处理事件总线事件...
});
}
aboutToDisappear() {
// 取消订阅CommonEvent
if (this.subscriber) {
commonEvent.unsubscribe(this.subscriber, (err) => {
if (err) {
console.error(`取消订阅失败: ${err.message}`);
}
});
this.subscriber = null;
}
// 取消订阅EventHub
if (this.listenerId !== -1) {
eventHub.off(this.listenerId);
this.listenerId = -1;
}
}
build() {
// 组件UI构建...
}
}
常见问题与解决方案
-
事件不被接收
- 检查事件名称是否正确匹配
- 确认订阅者已正确注册且未被销毁
- 验证发布者和订阅者的权限配置
-
内存泄漏
- 确保在组件销毁时取消所有事件订阅
- 避免在匿名内部类中保留外部对象引用
-
分布式事件问题
- 确认设备间已建立可信连接
- 验证设备属于同一帐户
- 检查网络连接状态
- 确认已启用分布式能力
高级主题:自定义事件处理器
对于特定场景,可以实现自定义事件处理器,提供专门的事件处理能力:
// 自定义事件处理器示例
import { EventHandler, EventRunner, InnerEvent } from '@ohos.events';
// 自定义事件类型
const EventType = {
NETWORK_CHANGE: 1001,
DATA_UPDATE: 1002,
USER_ACTION: 1003
};
// 自定义事件处理器
class CustomEventHandler extends EventHandler {
constructor(runner) {
super(runner);
// 初始化资源
}
// 重写事件处理方法
processEvent(event) {
console.log(`处理自定义事件: ${event.eventId}`);
switch (event.eventId) {
case EventType.NETWORK_CHANGE:
this.handleNetworkChange(event.data);
break;
case EventType.DATA_UPDATE:
this.handleDataUpdate(event.data);
break;
case EventType.USER_ACTION:
this.handleUserAction(event.data);
break;
default:
console.log(`未知事件类型: ${event.eventId}`);
}
}
// 专门的事件处理方法
handleNetworkChange(data) {
console.log(`网络状态变化: ${JSON.stringify(data)}`);
// 处理网络变化...
}
handleDataUpdate(data) {
console.log(`数据更新: ${JSON.stringify(data)}`);
// 处理数据更新...
}
handleUserAction(data) {
console.log(`用户操作: ${JSON.stringify(data)}`);
// 处理用户操作...
}
// 重写销毁方法,确保资源释放
destroy() {
console.log('销毁自定义事件处理器');
// 清理资源
super.destroy();
}
}
// 使用自定义事件处理器
function useCustomEventHandler() {
// 创建EventRunner
let runner = new EventRunner("CustomRunner");
// 创建自定义事件处理器
let handler = new CustomEventHandler(runner);
// 发送事件
handler.sendEvent({
eventId: EventType.NETWORK_CHANGE,
data: { status: "connected", type: "WIFI" }
});
// 在不需要时销毁
// handler.destroy();
return handler;
}
未来趋势与发展
鸿蒙系统的事件通知机制仍在持续演进,未来的发展方向包括:
- 增强的分布式能力:更强大的跨设备事件分发能力,支持更多场景
- AI辅助事件处理:基于用户行为预测事件重要性,优化处理顺序
- 事件处理效率提升:更高效的事件分发和处理机制
- 企业级安全特性:面向企业级应用的安全事件通知机制
- 更丰富的可视化通知形式:支持更多样化的通知展示方式
总结
鸿蒙系统提供了全面而强大的事件通知机制,从底层的EventHandler/EventRunner,到应用级的CommonEvent和Notification,再到分布式场景下的跨设备事件通知,构成了一个完整的事件处理生态系统。这套机制使得组件间通信更加便捷,系统状态变化更加透明,用户交互更加顺畅,为开发者构建高效、响应式的应用提供了坚实基础。
通过本文的详细介绍,开发者应当能够理解鸿蒙系统事件通知机制的核心原理和使用方法,并在实际应用开发中灵活运用这些能力,打造出功能丰富、体验流畅的鸿蒙应用。
更多推荐
所有评论(0)