# 桌面卡片更新机制修复 V2 ## 问题分析 从日志分析发现的关键问题: 1. **"batch update completed for 0 widgets"** - 批量更新时没有找到任何卡片 2. **状态反复切换** - isPlaying在true/false之间快速切换 3. **缺少全局监听器日志** - 没有看到全局监听器的设置消息 4. **多实例问题** - 可能有多个FormExtensionAbility实例,每个都有自己的formSizeMap ## 根本原因 1. **多实例冲突**:多个FormExtensionAbility实例共享同一个全局监听器,但各自维护独立的formSizeMap 2. **状态管理混乱**:卡片删除后,某些实例的formSizeMap变空,但全局监听器仍在运行 3. **重复更新**:onUpdateForm中同时调用单个更新和批量更新 ## 解决方案 V2 ### 1. 创建全局卡片管理器 创建了 `GlobalWidgetManager` 来统一管理所有活跃卡片: ```typescript export class GlobalWidgetManager { private static instance: GlobalWidgetManager | null = null; private static activeWidgets: Map = new Map(); // 注册卡片 public registerWidget(formId: string, size: WidgetSize): void // 注销卡片 public unregisterWidget(formId: string): void // 获取所有活跃卡片 public getActiveWidgets(): Map // 获取活跃卡片数量 public getActiveWidgetCount(): number } ``` ### 2. 修改EntryFormAbility - **移除本地formSizeMap**:使用全局管理器替代 - **统一卡片注册**:在onAddForm中注册到全局管理器 - **统一卡片注销**:在onRemoveForm中从全局管理器注销 - **全局状态检查**:更新前检查全局活跃卡片数量 ### 3. 关键修改点 #### A. 卡片注册 ```typescript // 旧代码 this.formSizeMap.set(formId, widgetSize); // 新代码 this.globalWidgetManager.registerWidget(formId, widgetSize); ``` #### B. 卡片注销 ```typescript // 旧代码 this.formSizeMap.delete(formId); // 新代码 this.globalWidgetManager.unregisterWidget(formId); ``` #### C. 全局监听器 ```typescript private setupGlobalStateListener(): void { const avSessionListener = AvSessionWidgetListener.getInstance(); avSessionListener.addStateListener((data: WidgetData) => { const activeWidgetCount = GlobalWidgetManager.getInstance().getActiveWidgetCount(); hilog.info(0x0000, TAG, `Global listener received update: widgets count: ${activeWidgetCount}`); // 只有当有活跃卡片时才更新 if (activeWidgetCount > 0) { this.updateAllWidgetsWithData(data); } else { hilog.info(0x0000, TAG, 'No active widgets, skipping update'); } }); } ``` #### D. 批量更新 ```typescript private updateAllWidgetsWithData(data: WidgetData): void { const activeWidgets = this.globalWidgetManager.getActiveWidgets(); hilog.info(0x0000, TAG, `Batch update called, active widgets: ${activeWidgets.size}`); if (activeWidgets.size === 0) { hilog.warn(0x0000, TAG, 'No widgets to update'); return; } // 更新所有活跃卡片... } ``` ## 预期效果 ### 应该看到的改进: 1. ✅ **正确的卡片计数**:批量更新显示正确的卡片数量,不再是0 2. ✅ **全局监听器日志**:看到 "global state listener setup successfully" 消息 3. ✅ **状态同步**:所有卡片状态保持一致,不再反复切换 4. ✅ **清晰的日志**:每次更新都显示正确的活跃卡片数量 ### 不应该再看到的问题: - ❌ "batch update completed for 0 widgets" - ❌ 状态在true/false之间快速无序切换 - ❌ 卡片删除后仍然尝试更新的错误 ## 测试要点 1. **启动测试**:启动应用,确认看到全局监听器设置消息 2. **卡片管理**:添加/删除卡片,观察全局管理器的注册/注销日志 3. **状态同步**:播放/暂停音乐,确认所有卡片同步更新 4. **批量更新**:确认批量更新显示正确的卡片数量 5. **多卡片测试**:添加多个卡片,确认都能正常工作 ## 架构改进 1. **单一数据源**:所有卡片信息统一由GlobalWidgetManager管理 2. **实例隔离**:多个FormExtensionAbility实例不再相互干扰 3. **状态一致性**:全局状态确保所有卡片保持同步 4. **资源管理**:更好的卡片生命周期管理,避免内存泄漏 这个修复应该彻底解决卡片更新的问题,提供更稳定和一致的用户体验。