# 卡片更新机制修复测试 ## 修复内容 ### 问题分析 1. **重复监听器问题**:每个卡片都注册了监听器,导致同一个状态更新被多次处理 2. **部分卡片更新失败**:某些卡片ID总是更新失败 3. **监听器重复触发**:同一个状态变化触发了多次监听器调用 ### 解决方案 1. ✅ **单一全局监听器**:只在 `initializeServices` 时设置一次监听器 2. ✅ **统一更新机制**:使用 `updateAllWidgetsWithData` 统一处理所有卡片 3. ✅ **避免重复注册**:移除了每个卡片的单独监听器注册 4. ✅ **简化初始化**:卡片初始化只负责初始数据加载 ## 代码修改 ### 1. 添加全局监听器标志 ```typescript private globalListenerSetup: boolean = false; ``` ### 2. 修改initializeServices方法 ```typescript private initializeServices(): void { if (!this.widgetDataManager) { this.widgetDataManager = new WidgetDataManager(); hilog.info(0x0000, TAG, 'WidgetDataManager initialized'); } // 设置全局状态监听器(只设置一次) if (!this.globalListenerSetup) { this.setupGlobalStateListener(); this.globalListenerSetup = true; } } ``` ### 3. 新增全局监听器设置方法 ```typescript private setupGlobalStateListener(): void { try { const avSessionListener = AvSessionWidgetListener.getInstance(); avSessionListener.addStateListener((data: WidgetData) => { hilog.info(0x0000, TAG, `Heanup widget global listener received state update: isPlaying=${data.playState.isPlaying}, title=${data.currentSong.title}`); // 更新所有活跃的卡片 this.updateAllWidgetsWithData(data); }); hilog.info(0x0000, TAG, 'Heanup widget global state listener setup successfully'); } catch (error) { hilog.error(0x0000, TAG, `Heanup widget failed to setup global listener: ${error}`); } } ``` ### 4. 新增统一更新方法 ```typescript private updateAllWidgetsWithData(data: WidgetData): void { this.formSizeMap.forEach((size: WidgetSize, formId: string) => { try { // 根据卡片尺寸适配数据 const adaptedData = this.layoutManager.adaptDataForSize(data, size); hilog.info(0x0000, TAG, `Heanup widget ${formId} calling formProvider.updateForm with isPlaying=${adaptedData.isPlaying}`); // 直接使用系统API更新卡片 const formData = formBindingData.createFormBindingData(adaptedData); formProvider.updateForm(formId, formData).then(() => { hilog.info(0x0000, TAG, `Heanup widget ${formId} updated successfully: isPlaying=${adaptedData.isPlaying}, title=${adaptedData.songTitle}`); }).catch((error) => { hilog.error(0x0000, TAG, `Heanup widget ${formId} update failed: ${error}`); }); } catch (error) { hilog.error(0x0000, TAG, `Heanup widget ${formId} process error: ${error}`); } }); } ``` ### 5. 简化initializeWidget方法 - 移除了重复的监听器注册 - 移除了定期更新机制 - 只保留初始化数据加载 ## 预期效果 ### 日志输出应该显示: 1. ✅ 只有一个 "global state listener setup successfully" 消息 2. ✅ 状态更新时只有一个 "global listener received state update" 消息 3. ✅ 所有活跃卡片都会被统一更新 4. ✅ 减少更新失败的情况 ### 不应该再看到: - ❌ 重复的监听器注册消息 - ❌ 同一个状态更新被多次处理 - ❌ 大量的更新失败消息 ## 测试步骤 1. 启动应用并添加桌面卡片 2. 播放音乐,观察日志输出 3. 暂停/播放切换,检查所有卡片是否同步更新 4. 添加多个卡片,验证统一更新机制 5. 检查日志中是否还有重复监听器问题 ## 关键改进点 1. **架构优化**:从"每卡片一个监听器"改为"全局单一监听器" 2. **性能提升**:减少了重复的监听器调用和状态处理 3. **稳定性增强**:统一的更新机制减少了更新失败的可能性 4. **代码简化**:移除了复杂的重复逻辑,提高了可维护性