HarmonyOS开发上下线通知

举报
Jack20 发表于 2026/06/19 20:50:05 2026/06/19
【摘要】 HarmonyOS开发上下线通知在分布式场景下,设备状态是动态变化的——手机可能随时离开、手表可能进入休眠、电视可能突然断电……如何实时感知这些状态变化,并及时做出响应,是分布式应用的基本功。这篇文章带你深入理解HarmonyOS设备状态监听的核心机制。 一、背景与动机:为什么需要设备状态监听? 1.1 设备状态的动态性在分布式场景下,设备状态变化频繁且不可预测:设备上线:新设备加入网络,...

HarmonyOS开发上下线通知

在分布式场景下,设备状态是动态变化的——手机可能随时离开、手表可能进入休眠、电视可能突然断电……如何实时感知这些状态变化,并及时做出响应,是分布式应用的基本功。这篇文章带你深入理解HarmonyOS设备状态监听的核心机制。

一、背景与动机:为什么需要设备状态监听?

1.1 设备状态的动态性

在分布式场景下,设备状态变化频繁且不可预测:

设备上线:新设备加入网络,可能带来新的能力,需要及时感知并更新设备列表。

设备下线:设备离开网络,可能正在执行的任务会中断,需要及时处理并恢复。

设备休眠:低功耗设备(如手表)会进入休眠状态,此时无法响应请求,需要等待唤醒。

设备唤醒:休眠设备被唤醒,能力重新可用,可以恢复之前暂停的任务。

状态切换:设备在不同状态间切换,如从在线变为繁忙、从空闲变为使用中。

1.2 状态监听的价值

实时监听设备状态变化,是保证分布式应用稳定运行的关键:
图片.png

状态监听的核心价值

状态变化 应用响应 用户价值
设备上线 更新设备列表、发现新能力 即时感知新设备
设备下线 中断任务、清理资源 避免操作失败
设备休眠 暂停任务、等待唤醒 节省功耗
设备唤醒 恢复任务、继续执行 无缝恢复
设备繁忙 排队请求、延迟执行 避免冲突

二、核心原理:设备状态模型

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 状态转换

图片.png

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}`);

六、总结

设备状态监听是分布式应用的基础能力,通过实时感知设备状态变化,及时做出响应,保证应用的稳定运行。

核心要点回顾

  1. 设备状态模型:完整的状态定义和转换规则
  2. 状态监听机制:事件分发、多监听器支持
  3. 状态监控策略:心跳检测、状态缓存
  4. 状态变化处理:上线、下线、休眠、唤醒等场景处理

最佳实践建议

  • 在组件销毁时取消监听,避免内存泄漏
  • 捕获监听器回调异常,保证其他监听器正常执行
  • 完整处理所有状态变化场景
  • 定期同步设备状态,避免状态不一致
  • 实现状态变化防抖,避免频繁变化影响性能
  • 使用兼容层适配多版本API

设备状态监听让分布式应用能够"感知"设备的变化,是实现智能协同的基础。


【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。