HarmonyOS开发上下线通知
HarmonyOS开发上下线通知
在分布式场景下,设备状态是动态变化的——手机可能随时离开、手表可能进入休眠、电视可能突然断电……如何实时感知这些状态变化,并及时做出响应,是分布式应用的基本功。这篇文章带你深入理解HarmonyOS设备状态监听的核心机制。
一、背景与动机:为什么需要设备状态监听?
1.1 设备状态的动态性
在分布式场景下,设备状态变化频繁且不可预测:
设备上线:新设备加入网络,可能带来新的能力,需要及时感知并更新设备列表。
设备下线:设备离开网络,可能正在执行的任务会中断,需要及时处理并恢复。
设备休眠:低功耗设备(如手表)会进入休眠状态,此时无法响应请求,需要等待唤醒。
设备唤醒:休眠设备被唤醒,能力重新可用,可以恢复之前暂停的任务。
状态切换:设备在不同状态间切换,如从在线变为繁忙、从空闲变为使用中。
1.2 状态监听的价值
实时监听设备状态变化,是保证分布式应用稳定运行的关键:

状态监听的核心价值:
| 状态变化 | 应用响应 | 用户价值 |
|---|---|---|
| 设备上线 | 更新设备列表、发现新能力 | 即时感知新设备 |
| 设备下线 | 中断任务、清理资源 | 避免操作失败 |
| 设备休眠 | 暂停任务、等待唤醒 | 节省功耗 |
| 设备唤醒 | 恢复任务、继续执行 | 无缝恢复 |
| 设备繁忙 | 排队请求、延迟执行 | 避免冲突 |
二、核心原理:设备状态模型
2.1 设备状态定义
HarmonyOS定义了完整的设备状态模型。
2.1.1 基础状态
// 设备基础状态枚举
enum DeviceState {
// 离线状态
OFFLINE = 0, // 离线(未连接)
// 在线状态
ONLINE = 1, // 在线(已连接)
READY = 2, // 就绪(可提供服务)
BUSY = 3, // 繁忙(正在使用中)
// 低功耗状态
IDLE = 4, // 空闲(等待任务)
SLEEP = 5, // 休眠(低功耗)
DEEP_SLEEP = 6, // 深度休眠(极低功耗)
// 异常状态
ERROR = 7, // 错误
UNKNOWN = 8 // 未知
}
2.1.2 状态转换

2.1.3 状态属性
// 设备状态属性
interface DeviceStateInfo {
deviceId: string; // 设备ID
state: DeviceState; // 当前状态
previousState: DeviceState; // 前一状态
// 状态时间
stateTime: number; // 状态变更时间
duration: number; // 当前状态持续时间
// 状态原因
reason: StateChangeReason; // 状态变更原因
detail: string; // 详细说明
// 附加信息
extra: Map<string, any>; // 扩展信息
}
// 状态变更原因枚举
enum StateChangeReason {
// 连接相关
REASON_CONNECT = 'connect', // 建立连接
REASON_DISCONNECT = 'disconnect', // 断开连接
REASON_AUTH_SUCCESS = 'auth_success', // 认证成功
REASON_AUTH_FAIL = 'auth_fail', // 认证失败
// 使用相关
REASON_START_USE = 'start_use', // 开始使用
REASON_END_USE = 'end_use', // 结束使用
REASON_TIMEOUT = 'timeout', // 超时
// 功耗相关
REASON_ENTER_IDLE = 'enter_idle', // 进入空闲
REASON_ENTER_SLEEP = 'enter_sleep', // 进入休眠
REASON_WAKEUP = 'wakeup', // 唤醒
// 异常相关
REASON_ERROR = 'error', // 发生错误
REASON_RECOVER = 'recover', // 错误恢复
// 用户操作
REASON_USER_ACTION = 'user_action' // 用户操作
}
2.2 状态监听机制
2.2.1 监听模型
// 状态监听器接口
interface DeviceStateListener {
// 设备状态变化回调
onDeviceStateChanged(info: DeviceStateInfo): void;
// 设备上线回调
onDeviceOnline(deviceId: string): void;
// 设备下线回调
onDeviceOffline(deviceId: string): void;
// 设备休眠回调
onDeviceSleep(deviceId: string): void;
// 设备唤醒回调
onDeviceWakeup(deviceId: string): void;
}
2.2.2 事件分发流程
sequenceDiagram
participant Device as 设备
participant Monitor as 状态监控器
participant Dispatcher as 事件分发器
participant Listener as 监听器
participant App as 应用
Note over Device: 1. 设备状态变化
Device->>Monitor: 状态变化事件
Note over Monitor: 2. 解析状态变化
Monitor->>Monitor: parseStateChange(event)
Monitor->>Monitor: updateDeviceState(deviceId, state)
Note over Monitor: 3. 构建状态信息
Monitor->>Monitor: buildStateInfo(deviceId, state)
Note over Dispatcher: 4. 分发事件
Monitor->>Dispatcher: dispatch(stateInfo)
Dispatcher->>Listener: onDeviceStateChanged(stateInfo)
Note over App: 5. 应用响应
Listener->>App: 触发应用回调
App->>App: handleStateChange(stateInfo)
classDef primary fill:#4A90E2,stroke:#2E5C8A,stroke-width:2px,color:#fff
classDef warning fill:#F5A623,stroke:#C17A00,stroke-width:2px,color:#fff
classDef info fill:#7ED321,stroke:#5BA315,stroke-width:2px,color:#fff
class Device,App primary
class Monitor,Dispatcher warning
class Listener info
2.3 状态监控策略
2.3.1 心跳检测
// 心跳检测配置
interface HeartbeatConfig {
enabled: boolean; // 是否启用
interval: number; // 心跳间隔(ms)
timeout: number; // 超时时间(ms)
retryCount: number; // 重试次数
adaptive: boolean; // 自适应间隔
}
// 心跳检测实现
class HeartbeatMonitor {
private config: HeartbeatConfig;
private timers: Map<string, number> = new Map();
/**
* 启动心跳检测
*/
startMonitor(deviceId: string): void {
if (!this.config.enabled) {
return;
}
// 设置定时器
const timerId = setInterval(() => {
this.sendHeartbeat(deviceId);
}, this.config.interval);
this.timers.set(deviceId, timerId);
}
/**
* 发送心跳
*/
private async sendHeartbeat(deviceId: string): Promise<void> {
try {
// 发送心跳请求
const response = await this.sendPing(deviceId);
if (response) {
// 心跳成功,重置超时计时器
this.resetTimeoutTimer(deviceId);
}
} catch (error) {
// 心跳失败,处理超时
this.handleHeartbeatFail(deviceId);
}
}
/**
* 处理心跳失败
*/
private handleHeartbeatFail(deviceId: string): void {
console.warn(`心跳失败: ${deviceId}`);
// 标记设备离线
this.notifyDeviceOffline(deviceId);
// 停止心跳检测
this.stopMonitor(deviceId);
}
/**
* 停止心跳检测
*/
stopMonitor(deviceId: string): void {
const timerId = this.timers.get(deviceId);
if (timerId) {
clearInterval(timerId);
this.timers.delete(deviceId);
}
}
}
2.3.2 状态缓存
// 状态缓存管理
class StateCacheManager {
private cache: Map<string, CachedState> = new Map();
private expireTime: number = 60000; // 缓存60秒
/**
* 获取设备状态
*/
getState(deviceId: string): DeviceState | null {
const cached = this.cache.get(deviceId);
if (!cached) {
return null;
}
// 检查是否过期
if (Date.now() - cached.timestamp > this.expireTime) {
this.cache.delete(deviceId);
return null;
}
return cached.state;
}
/**
* 更新设备状态
*/
updateState(deviceId: string, state: DeviceState): void {
this.cache.set(deviceId, {
state: state,
timestamp: Date.now()
});
}
/**
* 清除缓存
*/
clearCache(deviceId?: string): void {
if (deviceId) {
this.cache.delete(deviceId);
} else {
this.cache.clear();
}
}
}
// 缓存状态
interface CachedState {
state: DeviceState;
timestamp: number;
}
三、代码实战:状态监听实现
3.1 设备状态监听服务
import deviceManager from '@ohos.distributedHardware.deviceManager';
/**
* 设备状态监听服务
* 提供统一的设备状态监听能力
*/
export class DeviceStateMonitorService {
private deviceMgr: deviceManager.DeviceManager | null = null;
private listeners: Set<DeviceStateListener> = new Set();
private deviceStates: Map<string, DeviceStateInfo> = new Map();
private heartbeatMonitor: HeartbeatMonitor | null = null;
/**
* 初始化
*/
async initialize(bundleName: string): Promise<void> {
try {
// 创建设备管理器
this.deviceMgr = deviceManager.createDeviceManager(bundleName);
// 注册状态变化监听
this.deviceMgr.on('deviceStateChange', (data) => {
this.handleDeviceStateChange(data);
});
// 初始化心跳检测
this.heartbeatMonitor = new HeartbeatMonitor({
enabled: true,
interval: 5000, // 5秒心跳
timeout: 15000, // 15秒超时
retryCount: 3,
adaptive: true
});
console.info('[StateMonitor] 初始化成功');
} catch (error) {
console.error(`[StateMonitor] 初始化失败: ${JSON.stringify(error)}`);
throw error;
}
}
/**
* 添加状态监听器
*/
addListener(listener: DeviceStateListener): void {
this.listeners.add(listener);
// 立即通知当前设备状态
this.deviceStates.forEach((info, deviceId) => {
listener.onDeviceStateChanged(info);
});
}
/**
* 移除状态监听器
*/
removeListener(listener: DeviceStateListener): void {
this.listeners.delete(listener);
}
/**
* 获取设备当前状态
*/
getDeviceState(deviceId: string): DeviceStateInfo | undefined {
return this.deviceStates.get(deviceId);
}
/**
* 获取所有设备状态
*/
getAllDeviceStates(): DeviceStateInfo[] {
return Array.from(this.deviceStates.values());
}
/**
* 获取指定状态的设备列表
*/
getDevicesByState(state: DeviceState): string[] {
const devices: string[] = [];
this.deviceStates.forEach((info, deviceId) => {
if (info.state === state) {
devices.push(deviceId);
}
});
return devices;
}
/**
* 等待设备状态
*/
async waitForState(
deviceId: string,
targetState: DeviceState,
timeout: number = 30000
): Promise<boolean> {
return new Promise(resolve => {
const startTime = Date.now();
// 检查当前状态
const currentState = this.deviceStates.get(deviceId)?.state;
if (currentState === targetState) {
resolve(true);
return;
}
// 创建临时监听器
const tempListener: DeviceStateListener = {
onDeviceStateChanged: (info) => {
if (info.deviceId === deviceId && info.state === targetState) {
this.removeListener(tempListener);
resolve(true);
}
},
onDeviceOnline: () => {},
onDeviceOffline: () => {},
onDeviceSleep: () => {},
onDeviceWakeup: () => {}
};
this.addListener(tempListener);
// 设置超时
setTimeout(() => {
this.removeListener(tempListener);
resolve(false);
}, timeout);
});
}
/**
* 等待设备上线
*/
async waitForOnline(deviceId: string, timeout?: number): Promise<boolean> {
return this.waitForState(deviceId, DeviceState.ONLINE, timeout);
}
/**
* 等待设备就绪
*/
async waitForReady(deviceId: string, timeout?: number): Promise<boolean> {
return this.waitForState(deviceId, DeviceState.READY, timeout);
}
/**
* 处理设备状态变化
*/
private handleDeviceStateChange(data: deviceManager.DeviceStateChangeInfo): void {
const { deviceId, state } = data;
// 获取前一状态
const previousInfo = this.deviceStates.get(deviceId);
const previousState = previousInfo?.state || DeviceState.OFFLINE;
// 构建状态信息
const stateInfo: DeviceStateInfo = {
deviceId: deviceId,
state: state,
previousState: previousState,
stateTime: Date.now(),
duration: 0,
reason: this.inferChangeReason(previousState, state),
detail: '',
extra: new Map()
};
// 更新状态缓存
this.deviceStates.set(deviceId, stateInfo);
// 分发事件
this.dispatchEvent(stateInfo);
// 处理特殊状态
this.handleSpecialState(stateInfo);
console.info(`[StateMonitor] 设备状态变化: ${deviceId} ${previousState} -> ${state}`);
}
/**
* 推断状态变更原因
*/
private inferChangeReason(
previousState: DeviceState,
currentState: DeviceState
): StateChangeReason {
if (previousState === DeviceState.OFFLINE && currentState === DeviceState.ONLINE) {
return StateChangeReason.REASON_CONNECT;
}
if (currentState === DeviceState.OFFLINE) {
return StateChangeReason.REASON_DISCONNECT;
}
if (previousState === DeviceState.ONLINE && currentState === DeviceState.READY) {
return StateChangeReason.REASON_AUTH_SUCCESS;
}
if (previousState === DeviceState.READY && currentState === DeviceState.BUSY) {
return StateChangeReason.REASON_START_USE;
}
if (previousState === DeviceState.BUSY && currentState === DeviceState.READY) {
return StateChangeReason.REASON_END_USE;
}
if (currentState === DeviceState.SLEEP || currentState === DeviceState.DEEP_SLEEP) {
return StateChangeReason.REASON_ENTER_SLEEP;
}
if (previousState === DeviceState.SLEEP && currentState !== DeviceState.SLEEP) {
return StateChangeReason.REASON_WAKEUP;
}
return StateChangeReason.REASON_USER_ACTION;
}
/**
* 分发状态变化事件
*/
private dispatchEvent(stateInfo: DeviceStateInfo): void {
// 通知所有监听器
this.listeners.forEach(listener => {
try {
// 通用状态变化回调
listener.onDeviceStateChanged(stateInfo);
// 特定状态回调
switch (stateInfo.state) {
case DeviceState.ONLINE:
case DeviceState.READY:
if (stateInfo.previousState === DeviceState.OFFLINE) {
listener.onDeviceOnline(stateInfo.deviceId);
}
break;
case DeviceState.OFFLINE:
listener.onDeviceOffline(stateInfo.deviceId);
break;
case DeviceState.SLEEP:
case DeviceState.DEEP_SLEEP:
listener.onDeviceSleep(stateInfo.deviceId);
break;
default:
if (stateInfo.previousState === DeviceState.SLEEP) {
listener.onDeviceWakeup(stateInfo.deviceId);
}
break;
}
} catch (error) {
console.error(`[StateMonitor] 监听器回调异常: ${JSON.stringify(error)}`);
}
});
}
/**
* 处理特殊状态
*/
private handleSpecialState(stateInfo: DeviceStateInfo): void {
const { deviceId, state } = stateInfo;
switch (state) {
case DeviceState.ONLINE:
case DeviceState.READY:
// 设备上线,启动心跳检测
this.heartbeatMonitor?.startMonitor(deviceId);
break;
case DeviceState.OFFLINE:
// 设备离线,停止心跳检测
this.heartbeatMonitor?.stopMonitor(deviceId);
// 清理设备状态
this.deviceStates.delete(deviceId);
break;
case DeviceState.SLEEP:
case DeviceState.DEEP_SLEEP:
// 设备休眠,调整心跳间隔
// 可以延长心跳间隔以节省功耗
break;
}
}
/**
* 释放资源
*/
release(): void {
// 取消所有监听
this.deviceMgr?.off('deviceStateChange');
// 停止所有心跳检测
this.deviceStates.forEach((_, deviceId) => {
this.heartbeatMonitor?.stopMonitor(deviceId);
});
// 清空数据
this.listeners.clear();
this.deviceStates.clear();
console.info('[StateMonitor] 资源已释放');
}
}
3.2 状态变化处理器
/**
* 设备状态变化处理器
* 封装常见的状态变化处理逻辑
*/
export class DeviceStateHandler {
private taskManager: TaskManager | null = null;
private connectionManager: ConnectionManager | null = null;
/**
* 创建状态监听器
*/
createListener(): DeviceStateListener {
return {
onDeviceStateChanged: (info) => {
this.handleStateChange(info);
},
onDeviceOnline: (deviceId) => {
this.handleDeviceOnline(deviceId);
},
onDeviceOffline: (deviceId) => {
this.handleDeviceOffline(deviceId);
},
onDeviceSleep: (deviceId) => {
this.handleDeviceSleep(deviceId);
},
onDeviceWakeup: (deviceId) => {
this.handleDeviceWakeup(deviceId);
}
};
}
/**
* 处理状态变化
*/
private handleStateChange(info: DeviceStateInfo): void {
console.info(`[StateHandler] 状态变化: ${info.deviceId} -> ${info.state}`);
// 根据状态变化类型执行不同处理
switch (info.reason) {
case StateChangeReason.REASON_CONNECT:
this.onDeviceConnected(info.deviceId);
break;
case StateChangeReason.REASON_DISCONNECT:
this.onDeviceDisconnected(info.deviceId);
break;
case StateChangeReason.REASON_AUTH_SUCCESS:
this.onDeviceAuthenticated(info.deviceId);
break;
case StateChangeReason.REASON_ERROR:
this.onDeviceError(info.deviceId, info.detail);
break;
}
}
/**
* 处理设备上线
*/
private handleDeviceOnline(deviceId: string): void {
console.info(`[StateHandler] 设备上线: ${deviceId}`);
// 更新UI设备列表
this.updateDeviceList();
// 检查是否有待执行的任务
this.checkPendingTasks(deviceId);
}
/**
* 处理设备下线
*/
private handleDeviceOffline(deviceId: string): void {
console.info(`[StateHandler] 设备下线: ${deviceId}`);
// 更新UI设备列表
this.updateDeviceList();
// 处理正在执行的任务
this.handleRunningTasks(deviceId);
// 断开连接
this.connectionManager?.disconnect(deviceId);
}
/**
* 处理设备休眠
*/
private handleDeviceSleep(deviceId: string): void {
console.info(`[StateHandler] 设备休眠: ${deviceId}`);
// 暂停正在执行的任务
this.taskManager?.pauseTasks(deviceId);
// 更新设备状态显示
this.updateDeviceStatus(deviceId, '休眠中');
}
/**
* 处理设备唤醒
*/
private handleDeviceWakeup(deviceId: string): void {
console.info(`[StateHandler] 设备唤醒: ${deviceId}`);
// 恢复暂停的任务
this.taskManager?.resumeTasks(deviceId);
// 更新设备状态显示
this.updateDeviceStatus(deviceId, '在线');
}
/**
* 设备连接成功
*/
private onDeviceConnected(deviceId: string): void {
// 发起认证
this.connectionManager?.authenticate(deviceId);
}
/**
* 设备断开连接
*/
private onDeviceDisconnected(deviceId: string): void {
// 尝试重连
setTimeout(() => {
this.connectionManager?.reconnect(deviceId);
}, 3000);
}
/**
* 设备认证成功
*/
private onDeviceAuthenticated(deviceId: string): void {
// 设备就绪,可以开始使用
this.notifyDeviceReady(deviceId);
}
/**
* 设备发生错误
*/
private onDeviceError(deviceId: string, error: string): void {
console.error(`[StateHandler] 设备错误: ${deviceId}, ${error}`);
// 显示错误提示
this.showErrorDialog(`设备 ${deviceId} 发生错误: ${error}`);
}
/**
* 检查待执行任务
*/
private checkPendingTasks(deviceId: string): void {
const pendingTasks = this.taskManager?.getPendingTasks(deviceId);
if (pendingTasks && pendingTasks.length > 0) {
console.info(`[StateHandler] 发现${pendingTasks.length}个待执行任务`);
// 执行待执行任务
pendingTasks.forEach(task => {
this.taskManager?.executeTask(task);
});
}
}
/**
* 处理正在执行的任务
*/
private handleRunningTasks(deviceId: string): void {
const runningTasks = this.taskManager?.getRunningTasks(deviceId);
if (runningTasks && runningTasks.length > 0) {
console.info(`[StateHandler] 有${runningTasks.length}个任务正在执行`);
// 暂停任务并标记为待重试
runningTasks.forEach(task => {
this.taskManager?.pauseTask(task.taskId);
this.taskManager?.markAsPending(task.taskId);
});
}
}
// 辅助方法(简化实现)
private updateDeviceList(): void {}
private updateDeviceStatus(deviceId: string, status: string): void {}
private notifyDeviceReady(deviceId: string): void {}
private showErrorDialog(message: string): void {}
}
// 任务管理器(简化定义)
interface TaskManager {
pauseTasks(deviceId: string): void;
resumeTasks(deviceId: string): void;
getPendingTasks(deviceId: string): Task[];
getRunningTasks(deviceId: string): Task[];
executeTask(task: Task): void;
pauseTask(taskId: string): void;
markAsPending(taskId: string): void;
}
interface Task {
taskId: string;
deviceId: string;
}
// 连接管理器(简化定义)
interface ConnectionManager {
disconnect(deviceId: string): void;
authenticate(deviceId: string): void;
reconnect(deviceId: string): void;
}
3.3 设备状态UI组件
/**
* 设备状态监控面板
* 实时显示设备状态变化
*/
@Component
export struct DeviceStateMonitorPanel {
@State deviceStates: DeviceStateInfo[] = [];
@State selectedDevice: string = '';
private monitorService: DeviceStateMonitorService | null = null;
aboutToAppear(): void {
this.initializeMonitor();
}
private async initializeMonitor(): Promise<void> {
this.monitorService = new DeviceStateMonitorService();
await this.monitorService.initialize('com.example.app');
// 添加监听器
this.monitorService.addListener({
onDeviceStateChanged: (info) => {
this.updateDeviceStates();
},
onDeviceOnline: (deviceId) => {
this.showNotification(`${deviceId} 已上线`);
},
onDeviceOffline: (deviceId) => {
this.showNotification(`${deviceId} 已下线`);
},
onDeviceSleep: (deviceId) => {
this.showNotification(`${deviceId} 进入休眠`);
},
onDeviceWakeup: (deviceId) => {
this.showNotification(`${deviceId} 已唤醒`);
}
});
// 加载初始状态
this.updateDeviceStates();
}
private updateDeviceStates(): void {
this.deviceStates = this.monitorService?.getAllDeviceStates() || [];
}
build() {
Column() {
// 标题
Row() {
Text('设备状态监控')
.fontSize(20)
.fontWeight(FontWeight.Bold)
Blank()
Text(`共${this.deviceStates.length}个设备`)
.fontSize(14)
.fontColor('#666666')
}
.width('100%')
.padding(16)
Divider()
// 设备列表
if (this.deviceStates.length > 0) {
List() {
ForEach(this.deviceStates, (info: DeviceStateInfo) => {
ListItem() {
this.DeviceStateItem(info)
}
}, (info: DeviceStateInfo) => info.deviceId)
}
.width('100%')
.layoutWeight(1)
} else {
Column() {
Text('暂无设备')
.fontSize(16)
.fontColor('#999999')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
@Builder
DeviceStateItem(info: DeviceStateInfo) {
Column() {
// 设备信息行
Row() {
// 设备图标
Circle()
.width(48)
.height(48)
.fill(this.getStateColor(info.state))
// 设备信息
Column() {
Text(info.deviceId.substring(0, 8))
.fontSize(16)
.fontWeight(FontWeight.Medium)
Text(this.getStateText(info.state))
.fontSize(14)
.fontColor('#666666')
.margin({ top: 4 })
}
.alignItems(HorizontalAlign.Start)
.margin({ left: 12 })
.layoutWeight(1)
// 状态指示器
Column() {
Circle()
.width(12)
.height(12)
.fill(this.getStateIndicatorColor(info.state))
Text(this.getStateDuration(info))
.fontSize(12)
.fontColor('#999999')
.margin({ top: 4 })
}
}
.width('100%')
// 状态变化信息
Row() {
Text(`前一状态: ${this.getStateText(info.previousState)}`)
.fontSize(12)
.fontColor('#999999')
Blank()
Text(`原因: ${this.getReasonText(info.reason)}`)
.fontSize(12)
.fontColor('#999999')
}
.width('100%')
.margin({ top: 8 })
}
.width('100%')
.padding(16)
.backgroundColor(Color.White)
.borderRadius(8)
.margin({ bottom: 8 })
}
/**
* 获取状态文本
*/
private getStateText(state: DeviceState): string {
const stateMap: Record<DeviceState, string> = {
[DeviceState.OFFLINE]: '离线',
[DeviceState.ONLINE]: '在线',
[DeviceState.READY]: '就绪',
[DeviceState.BUSY]: '繁忙',
[DeviceState.IDLE]: '空闲',
[DeviceState.SLEEP]: '休眠',
[DeviceState.DEEP_SLEEP]: '深度休眠',
[DeviceState.ERROR]: '错误',
[DeviceState.UNKNOWN]: '未知'
};
return stateMap[state] || '未知';
}
/**
* 获取状态颜色
*/
private getStateColor(state: DeviceState): ResourceColor {
const colorMap: Record<DeviceState, ResourceColor> = {
[DeviceState.OFFLINE]: '#CCCCCC',
[DeviceState.ONLINE]: '#4A90E2',
[DeviceState.READY]: '#7ED321',
[DeviceState.BUSY]: '#F5A623',
[DeviceState.IDLE]: '#7ED321',
[DeviceState.SLEEP]: '#9B59B6',
[DeviceState.DEEP_SLEEP]: '#9B59B6',
[DeviceState.ERROR]: '#D0021B',
[DeviceState.UNKNOWN]: '#CCCCCC'
};
return colorMap[state] || '#CCCCCC';
}
/**
* 获取状态指示器颜色
*/
private getStateIndicatorColor(state: DeviceState): ResourceColor {
if (state === DeviceState.READY || state === DeviceState.ONLINE) {
return '#7ED321';
}
if (state === DeviceState.OFFLINE || state === DeviceState.ERROR) {
return '#D0021B';
}
return '#F5A623';
}
/**
* 获取状态持续时间
*/
private getStateDuration(info: DeviceStateInfo): string {
const duration = Date.now() - info.stateTime;
if (duration < 60000) {
return `${Math.floor(duration / 1000)}秒`;
}
if (duration < 3600000) {
return `${Math.floor(duration / 60000)}分钟`;
}
return `${Math.floor(duration / 3600000)}小时`;
}
/**
* 获取原因文本
*/
private getReasonText(reason: StateChangeReason): string {
const reasonMap: Record<StateChangeReason, string> = {
[StateChangeReason.REASON_CONNECT]: '连接',
[StateChangeReason.REASON_DISCONNECT]: '断开',
[StateChangeReason.REASON_AUTH_SUCCESS]: '认证成功',
[StateChangeReason.REASON_AUTH_FAIL]: '认证失败',
[StateChangeReason.REASON_START_USE]: '开始使用',
[StateChangeReason.REASON_END_USE]: '结束使用',
[StateChangeReason.REASON_TIMEOUT]: '超时',
[StateChangeReason.REASON_ENTER_IDLE]: '进入空闲',
[StateChangeReason.REASON_ENTER_SLEEP]: '进入休眠',
[StateChangeReason.REASON_WAKEUP]: '唤醒',
[StateChangeReason.REASON_ERROR]: '错误',
[StateChangeReason.REASON_RECOVER]: '恢复',
[StateChangeReason.REASON_USER_ACTION]: '用户操作'
};
return reasonMap[reason] || '未知';
}
private showNotification(message: string): void {
console.info(`[通知] ${message}`);
}
aboutToDisappear(): void {
this.monitorService?.release();
}
}
四、踩坑与注意事项
4.1 监听相关
坑1:忘记取消监听
监听器未取消会导致内存泄漏和重复回调。
// ❌ 错误做法:只注册不取消
aboutToAppear(): void {
monitorService.addListener(this.listener);
}
// 缺少aboutToDisappear中的取消
// ✅ 正确做法:在组件销毁时取消
aboutToDisappear(): void {
monitorService.removeListener(this.listener);
}
坑2:监听器回调异常
监听器回调异常会影响其他监听器。
// ✅ 正确做法:捕获回调异常
private dispatchEvent(info: DeviceStateInfo): void {
this.listeners.forEach(listener => {
try {
listener.onDeviceStateChanged(info);
} catch (error) {
console.error(`监听器回调异常: ${error}`);
// 继续执行其他监听器
}
});
}
4.2 状态处理相关
坑3:状态变化遗漏
某些状态变化场景未处理。
// ✅ 正确做法:完整处理所有状态变化
private handleStateChange(info: DeviceStateInfo): void {
switch (info.state) {
case DeviceState.OFFLINE:
this.handleOffline(info);
break;
case DeviceState.ONLINE:
this.handleOnline(info);
break;
case DeviceState.READY:
this.handleReady(info);
break;
case DeviceState.BUSY:
this.handleBusy(info);
break;
case DeviceState.SLEEP:
case DeviceState.DEEP_SLEEP:
this.handleSleep(info);
break;
case DeviceState.ERROR:
this.handleError(info);
break;
default:
console.warn(`未处理的状态: ${info.state}`);
}
}
坑4:状态不一致
缓存状态与实际状态不一致。
// ✅ 正确做法:定期同步状态
async syncDeviceStates(): Promise<void> {
const devices = await this.deviceMgr?.getTrustedDeviceList(true);
for (const device of devices || []) {
const actualState = device.state;
const cachedState = this.deviceStates.get(device.deviceId)?.state;
if (actualState !== cachedState) {
// 状态不一致,更新缓存并通知
this.handleDeviceStateChange({
deviceId: device.deviceId,
state: actualState
});
}
}
}
4.3 性能相关
坑5:频繁状态变化导致性能问题
设备状态频繁变化会影响性能。
// ✅ 正确做法:实现状态变化防抖
class DebouncedStateHandler {
private pendingChanges: Map<string, number> = new Map();
private debounceTime: number = 1000; // 1秒防抖
handleStateChange(info: DeviceStateInfo): void {
const now = Date.now();
const lastChange = this.pendingChanges.get(info.deviceId) || 0;
if (now - lastChange < this.debounceTime) {
// 忽略频繁变化
return;
}
this.pendingChanges.set(info.deviceId, now);
// 处理状态变化
this.doHandleStateChange(info);
}
}
五、HarmonyOS 6适配指南
5.1 API变更
状态监听API增强:
// HarmonyOS 5.0
deviceMgr.on('deviceStateChange', callback);
// HarmonyOS 6.0
import { DeviceStateMonitor } from '@ohos.distributedHardware.stateMonitor';
const monitor = DeviceStateMonitor.getInstance();
// 支持更细粒度的监听
monitor.on('stateChanged', callback);
monitor.on('online', callback); // 单独监听上线
monitor.on('offline', callback); // 单独监听下线
monitor.on('sleep', callback); // 单独监听休眠
monitor.on('wakeup', callback); // 单独监听唤醒
5.2 行为变更
变更1:状态预测
HarmonyOS 6新增状态预测能力。
// HarmonyOS 6新增状态预测
const prediction = await monitor.predictState(deviceId, {
horizon: 30000 // 预测未来30秒
});
console.info(`预测状态: ${prediction.state}, 概率: ${prediction.probability}`);
变更2:状态历史
// HarmonyOS 6新增状态历史查询
const history = await monitor.getStateHistory(deviceId, {
startTime: Date.now() - 3600000, // 最近1小时
endTime: Date.now()
});
console.info(`状态变化历史: ${history.length}次`);
六、总结
设备状态监听是分布式应用的基础能力,通过实时感知设备状态变化,及时做出响应,保证应用的稳定运行。
核心要点回顾:
- 设备状态模型:完整的状态定义和转换规则
- 状态监听机制:事件分发、多监听器支持
- 状态监控策略:心跳检测、状态缓存
- 状态变化处理:上线、下线、休眠、唤醒等场景处理
最佳实践建议:
- 在组件销毁时取消监听,避免内存泄漏
- 捕获监听器回调异常,保证其他监听器正常执行
- 完整处理所有状态变化场景
- 定期同步设备状态,避免状态不一致
- 实现状态变化防抖,避免频繁变化影响性能
- 使用兼容层适配多版本API
设备状态监听让分布式应用能够"感知"设备的变化,是实现智能协同的基础。
- 点赞
- 收藏
- 关注作者
评论(0)