Appearance
广播与事件(CommonEvent)
1. CommonEvent 概述
CommonEvent 是鸿蒙系统的发布-订阅广播机制:
┌──────────────────────────────────────────────────┐
│ CommonEvent 特性 │
│ ├── 发布-订阅模式:发布者不感知订阅者 │
│ ├── 系统级广播:系统事件通过 CommonEvent 广播 │
│ ├── 支持跨应用通信:不同应用通过事件名订阅 │
│ ├── 异步通信:发布后立即返回,不等待处理完成 │
│ ├── 有序/无序广播:通过 flags 区分 │
│ └── 订阅限流:每个应用对同一事件最多订阅 100 次 │
└──────────────────────────────────────────────────┘2. CommonEvent 发布
2.1 发布 CommonEvent
arkts
import { common } from '@kit.AbilityKit';
// 1. 发布有序事件(有序广播)
async function publishOrderedEvent() {
const want: common.EventWant = {
action: 'com.example.action.MY_EVENT',
parameters: {
key1: 'value1',
key2: 100
}
};
const publishInfo: common.PublishOptions = {
permissions: ['ohos.permission.BROADCAST_COMMON'], // 需要权限
flags: common.Flags.FLAG_OWNED_SYNC, // 同步等待
};
await common.publishEvent('com.example.action.MY_EVENT', want, publishInfo);
}
// 2. 发布无序事件(无序广播)
async function publishUnorderedEvent() {
const want: common.EventWant = {
action: 'com.example.action.MY_EVENT_ASYNC',
parameters: {
key1: 'value1'
}
};
// 无序:不需要权限
await common.publishEvent('com.example.action.MY_EVENT_ASYNC', want);
}
// 3. 发布系统事件
async function publishSystemEvent() {
const want: common.EventWant = {
action: 'com.huawei.system.bootup', // 系统启动事件
parameters: {
bootType: 'cold'
}
};
await common.publishEvent(want.action, want);
}2.2 系统内置事件
| 事件名(Action) | 说明 | 触发时机 |
|---|---|---|
com.huawei.system.bootup | 系统启动完成 | 开机完成后 |
com.huawei.intent.action.USER_PRESENT | 用户解锁设备 | 解锁时 |
com.huawei.intent.action.ACTION_POWER_CONNECTED | 充电器连接 | 插拔充电器 |
com.huawei.intent.action.ACTION_POWER_DISCONNECTED | 充电器断开 | 拔充电器 |
ohos.action.internetConnectivityChange | 网络连通性变化 | 网络切换时 |
ohos.action.timeChange | 时间变更 | 时间变化 |
ohos.action.timezoneChange | 时区变更 | 时区变化 |
com.huawei.intent.action.PACKAGE_ADDED | 应用安装 | 安装完成 |
com.huawei.intent.action.PACKAGE_REMOVED | 应用卸载 | 卸载完成 |
ohos.wifi.WIFI_STATE_CHANGED | WiFi 状态变化 | WiFi 开关 |
3. CommonEvent 订阅
3.1 订阅 CommonEvent
arkts
import { common } from '@kit.AbilityKit';
// 1. 订阅事件(需要订阅者)
interface MySubscriber extends common.Subscriber {
onReceiveEvent(want: common.EventWant): void {
console.log(`Received event: ${want.action}`);
console.log(`Parameters:`, want.parameters);
}
}
// 2. 创建订阅者
const mySubscriber: common.Subscriber = {
wantList: [
{
actions: [
'com.example.action.MY_EVENT',
'com.example.action.MY_EVENT_ASYNC',
]
}
],
onReceiveEvent(want: common.EventWant) {
console.log('Received: ' + want.action);
console.log('Params:', want.parameters);
}
};
// 3. 注册订阅
const subscriberId = await common.subscribe(mySubscriber);
console.log('Subscriber ID: ' + subscriberId);
// 4. 取消订阅
async function unsubscribeEvent() {
await common.unsubscribe(subscriberId);
}3.2 事件过滤器
arkts
// 订阅过滤器:匹配特定事件
import { common } from '@kit.AbilityKit';
const filter: common.SubscriberOptions = {
wantList: [
{
actions: ['com.example.action.MY_EVENT'],
entities: ['entity.default'],
URI: 'uri://example.com/event',
parameters: {
key1: 'value1' // 参数过滤
}
}
]
};
const subscriber = {
wantList: filter.wantList,
onReceiveEvent: (want: common.EventWant) => {
// 处理匹配的事件
}
};
const id = await common.subscribe(subscriber);4. 权限与安全
4.1 权限要求
发布权限:
├── 无序 CommonEvent:不需要特殊权限(ohos.permission.BROADCAST_COMMON)
├── 有序 CommonEvent:需要 ohos.permission.BROADCAST_COMMON
└── 系统级事件:需要系统权限(ohos.permission.SYSTEM_BROADCAST)
订阅权限:
├── 无序事件:无需权限
├── 有序事件:需与发布方相同权限
└── 系统事件:需对应系统权限4.2 安全限制
安全限制:
├── 事件名规范:需以应用 bundleName 为前缀(防止冲突)
├── 消息大小限制:单次事件数据不超过 1MB
├── 订阅次数限制:同一事件最多订阅 100 次/应用
├── 发布频率限制:防止滥用导致系统负载过高
└── 跨应用隔离:不可发布/订阅其他应用的私有事件5. CommonEvent 与 Android Broadcast 对比
| 维度 | Android BroadcastReceiver | 鸿蒙 CommonEvent |
|---|---|---|
| 通信模式 | 发布-订阅 | 发布-订阅 |
| 有序/无序 | 有序/无序广播 | 通过 flags 区分 |
| 权限控制 | 权限声明 + 动态权限 | 发布权限 + 订阅权限 |
| 事件类型 | Intent Action | Want Action + parameters |
| 注册方式 | Manifest 静态 / 动态 | 动态注册 |
| 执行线程 | 主线程(可能导致 ANR) | 异步(不阻塞主线程) |
| 超时限制 | 有序广播 10s 超时 | 无固定超时(FLAG_OWNED_SYNC) |
| 系统事件 | AndroidManifest 定义 | CommonEvent 预定义 |
| 性能 | BroadcastReceiver 开销大 | CommonEvent 更轻量 |
6. 使用场景
6.1 跨 Ability 通信
arkts
// Ability A:发布事件
async function notifyAbilityB() {
const want: common.EventWant = {
action: 'com.example.app.ACTION_UPDATE',
parameters: { data: 'new_data', timestamp: Date.now() }
};
await common.publishEvent(want.action, want);
}
// Ability B:订阅事件
const subscriber: common.Subscriber = {
wantList: [{ actions: ['com.example.app.ACTION_UPDATE'] }],
onReceiveEvent(want: common.EventWant) {
const { data, timestamp } = want.parameters;
this.refreshData(data);
console.log(`Updated at ${timestamp}`);
}
};
const subId = await common.subscribe(subscriber);6.2 系统状态监听
arkts
// 监听网络状态变化
import { common } from '@kit.AbilityKit';
import { net } from '@kit.NetworkKit';
// 方式一:通过 CommonEvent 监听
const networkSubscriber: common.Subscriber = {
wantList: [{ actions: ['ohos.action.internetConnectivityChange'] }],
onReceiveEvent(want: common.EventWant) {
const networkInfo = net.getNetworkInfo();
console.log('Network: ' + networkInfo.connected);
}
};
await common.subscribe(networkSubscriber);
// 方式二:使用 net 模块(推荐)
import { net } from '@kit.NetworkKit';
net.on('connectivityChange', (info: net.NetChangeInfo) => {
console.log('Connected: ' + info.connected);
});7. 🎯 面试高频考点
Q1: CommonEvent 与 Android Broadcast 的区别?
答要点:
- 执行线程:Android Broadcast 在主线程(可能 ANR),CommonEvent 异步
- 注册方式:Android 支持静态(Manifest)和动态,鸿蒙仅支持动态注册
- 超时处理:Android 有序广播有 10s 超时,鸿蒙无固定超时
- 性能:CommonEvent 更轻量,广播更安全
- 权限:CommonEvent 发布/订阅均需验证权限,更安全
Q2: CommonEvent 的有序和无序有什么区别?
答要点:
- 有序:通过 FLAG_OWNED_SYNC 等 flag 控制,按优先级顺序依次传递
- 无序:同时传递给所有订阅者,不等待处理
- 权限:有序需要权限,无序不需要
- 使用场景:有序用于需要确认的场景(如系统关键事件),无序用于通知场景
Q3: CommonEvent 的订阅限制?
答要点:
- 同一应用对同一事件最多订阅 100 次
- 事件数据不超过 1MB
- 事件名需以 bundleName 为前缀
- 发布无序事件无需权限,有序需要 BROADCAST_COMMON 权限
- 系统级事件需要 SYSTEM_BROADCAST 权限
💡 面试提示:重点掌握 发布-订阅机制、有序/无序区别、权限控制。对比 Android Broadcast 时强调 异步执行 和 安全性。