Skip to content

事件总线与订阅

鸿蒙通过 CommonEvent 实现跨 Ability/进程的事件通信。


1. CommonEvent 概述

1.1 核心概念

CommonEvent 是鸿蒙的发布订阅事件系统,支持跨 Ability、跨进程的事件传递。

特性说明
发布/订阅模式发布者发布事件,订阅者监听
跨进程支持跨 Ability/进程通信
同步/异步支持同步和异步订阅
优先级支持事件优先级
系统事件内置系统事件(电池、网络、时间等)

2. 发布事件

2.1 发布普通事件

typescript
import { commonEventManager } from '@kit.AbilityKit'

// 发布同步事件(等待所有订阅者处理完)
let eventInfo: commonEventManager.CommonEventInfo = {
    action: 'com.example.app.action.DATA_CHANGED',
    data: '新数据已更新',
    extraData: {
        key: 'value'
    }
}

commonEventManager.publish(eventInfo).then(() => {
    console.log('事件发布成功')
}).catch((err: BusinessError) => {
    console.error('事件发布失败:', err.message)
})

// 发布异步事件(不等待)
commonEventManager.publishAsync(eventInfo).then(() => {
    console.log('异步事件发布成功')
})

2.2 发布系统事件

typescript
// 发布系统电池事件
let batteryEvent: commonEventManager.CommonEventInfo = {
    action: 'system.battery.change',
    data: 'battery_level=50'
}

commonEventManager.publishAsync(batteryEvent)

3. 订阅事件

3.1 同步订阅

typescript
import { commonEventManager } from '@kit.AbilityKit'

// 定义订阅条件
let subscriber: commonEventManager.CommonEventSubscriber = {
    events: [
        'com.example.app.action.DATA_CHANGED',
        'system.battery.change'
    ]
}

// 同步订阅
let syncSubscriber = commonEventManager.subscribe(subscriber, (err, data) => {
    if (err) {
        console.error('订阅失败:', err.message)
        return
    }
    
    console.log('收到事件:', data.action)
    console.log('数据:', data.data)
    console.log('额外数据:', JSON.stringify(data.extraData))
})

3.2 异步订阅

typescript
let subscriber: commonEventManager.CommonEventSubscriber = {
    events: ['com.example.app.action.DATA_CHANGED']
}

// 异步订阅
let asyncSubscriber = commonEventManager.subscribeAsync(subscriber, (err, data) => {
    if (err) {
        console.error('订阅失败:', err.message)
        return
    }
    
    console.log('收到事件:', data.action)
})

4. 取消订阅

typescript
// 取消订阅
commonEventManager.unsubscribe(syncSubscriber).then(() => {
    console.log('取消订阅成功')
}).catch((err: BusinessError) => {
    console.error('取消订阅失败:', err.message)
})

commonEventManager.unsubscribeAsync(asyncSubscriber)

5. 实际应用场景

5.1 跨 Ability 通知

typescript
// Ability A:发布通知
function notifyDataChanged() {
    let eventInfo: commonEventManager.CommonEventInfo = {
        action: 'com.example.app.action.DATA_CHANGED',
        data: '数据已更新'
    }
    commonEventManager.publishAsync(eventInfo)
}

// Ability B:订阅通知
let subscriber: commonEventManager.CommonEventSubscriber = {
    events: ['com.example.app.action.DATA_CHANGED']
}

commonEventManager.subscribe(subscriber, (err, data) => {
    if (err) return
    // 收到通知,刷新 UI
    this.refreshUI()
})

5.2 系统事件监听

typescript
// 监听网络变化
let networkSubscriber: commonEventManager.CommonEventSubscriber = {
    events: ['system.network.change']
}

commonEventManager.subscribe(networkSubscriber, (err, data) => {
    if (data && data.data === 'connected') {
        console.log('网络已连接')
    } else if (data && data.data === 'disconnected') {
        console.log('网络已断开')
    }
})

6. 内置系统事件

事件说明
system.battery.change电池电量变化
system.network.change网络状态变化
system.time.change时间变化
system.timezone.change时区变化
system.screen.on屏幕点亮
system.screen.off屏幕熄灭
system.device.locked设备锁定
system.device.unlocked设备解锁

7. 面试高频考点

Q1: CommonEvent 的作用?

回答:鸿蒙的发布订阅事件系统,支持跨 Ability/进程的事件传递。有系统内置事件(电池、网络等)和自定义事件。

Q2: 订阅和取消订阅的流程?

回答:定义 subscriber(事件列表),subscribe/subscribeAsync 订阅,unsubscribe/unsubscribeAsync 取消订阅。


🐱 小猫提示:CommonEvent 记住 "发布/订阅、跨进程、系统事件内置"