卡片更新机制修复测试
修复内容
问题分析
- 重复监听器问题:每个卡片都注册了监听器,导致同一个状态更新被多次处理
- 部分卡片更新失败:某些卡片ID总是更新失败
- 监听器重复触发:同一个状态变化触发了多次监听器调用
解决方案
- ✅ 单一全局监听器:只在
initializeServices 时设置一次监听器
- ✅ 统一更新机制:使用
updateAllWidgetsWithData 统一处理所有卡片
- ✅ 避免重复注册:移除了每个卡片的单独监听器注册
- ✅ 简化初始化:卡片初始化只负责初始数据加载
代码修改
1. 添加全局监听器标志
private globalListenerSetup: boolean = false;
2. 修改initializeServices方法
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. 新增全局监听器设置方法
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. 新增统一更新方法
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方法
- 移除了重复的监听器注册
- 移除了定期更新机制
- 只保留初始化数据加载
预期效果
日志输出应该显示:
- ✅ 只有一个 "global state listener setup successfully" 消息
- ✅ 状态更新时只有一个 "global listener received state update" 消息
- ✅ 所有活跃卡片都会被统一更新
- ✅ 减少更新失败的情况
不应该再看到:
- ❌ 重复的监听器注册消息
- ❌ 同一个状态更新被多次处理
- ❌ 大量的更新失败消息
测试步骤
- 启动应用并添加桌面卡片
- 播放音乐,观察日志输出
- 暂停/播放切换,检查所有卡片是否同步更新
- 添加多个卡片,验证统一更新机制
- 检查日志中是否还有重复监听器问题
关键改进点
- 架构优化:从"每卡片一个监听器"改为"全局单一监听器"
- 性能提升:减少了重复的监听器调用和状态处理
- 稳定性增强:统一的更新机制减少了更新失败的可能性
- 代码简化:移除了复杂的重复逻辑,提高了可维护性