widget_fix_v6_summary.md 3.6 KB

Widget Fix V6 - 解决重复更新和数据同步问题

新发现的问题

从最新日志分析发现了以下问题:

1. 重复更新问题

  • 每个CommonEvent事件触发多次widget更新
  • AvSession监听器和CommonEvent监听器都在处理同一个事件
  • 导致widget被重复更新,浪费资源

2. 数据同步不一致

  • 主应用进程显示 listeners=0
  • Form进程显示 listeners=2
  • 主应用状态为 isPlaying=true,但form进程有时显示 isPlaying=false

3. 监听器架构混乱

  • PlayerControlService同时注册了CommonEvent和AvSession监听器
  • 两个监听器都在处理相同的数据,造成重复处理

修复方案

1. 简化事件处理流程

文件: entry/src/main/ets/common/widget/PlayerControlService.ets

// 修改前:CommonEvent和AvSession都通知stateListeners
// 修改后:只通过AvSession统一处理,避免重复通知

private handlePlayerStateChange(eventData: commonEventManager.CommonEventData): void {
  // 只更新AvSession监听器的数据,避免重复通知
  // AvSession监听器会自动通知所有注册的监听器
  this.avSessionListener.updateWidgetData(widgetData);
}

2. 添加数据变化检测

文件: entry/src/main/ets/common/widget/AvSessionWidgetListener.ets

// 添加数据相等性检查,避免无意义的更新
private isDataEqual(data1: WidgetData, data2: WidgetData): boolean {
  return data1.playState.isPlaying === data2.playState.isPlaying &&
         data1.currentSong.title === data2.currentSong.title &&
         // ... 其他关键字段比较
}

3. 添加防抖机制

文件: entry/src/main/ets/entryformability/EntryFormAbility.ets

// 添加100ms防抖延迟,避免短时间内重复更新
private updateDebounceDelay: number = 100;

private updateAllWidgetsWithData(data: WidgetData): void {
  const now = Date.now();
  if (now - this.lastUpdateTime < this.updateDebounceDelay) {
    return; // 跳过重复更新
  }
  // ... 执行更新
}

优化后的数据流

新的事件处理流程

  1. 主应用 → 发送CommonEvent
  2. Form进程 → PlayerControlService接收CommonEvent
  3. PlayerControlService → 更新AvSessionWidgetListener数据
  4. AvSessionWidgetListener → 检查数据变化,通知监听器
  5. EntryFormAbility → 防抖检查,更新widget UI

关键改进

  • 单一数据源:所有更新都通过AvSessionWidgetListener统一处理
  • 重复检测:避免相同数据的重复更新
  • 防抖机制:短时间内的多次更新被合并
  • 进程隔离修复:每个进程都能正确设置监听器

预期效果

性能优化

  • 减少不必要的widget更新调用
  • 降低CPU和内存使用
  • 提高响应速度

数据一致性

  • 确保所有widget显示相同的播放状态
  • 消除主应用和form进程间的数据不同步

稳定性提升

  • 减少重复更新导致的潜在错误
  • 提高长时间运行的稳定性

测试要点

  1. 基本功能:播放/暂停按钮响应正常
  2. 数据同步:所有widget状态保持一致
  3. 性能表现:更新频率合理,无重复调用
  4. 长期稳定性:长时间使用后仍能正常更新

日志监控

关键日志模式:

  • Data unchanged, skipping update - 重复数据被过滤
  • update debounced, skipping - 防抖机制生效
  • Widget data updated and broadcasted to X listeners - 监听器数量正常
  • 减少重复的 formProvider.updateForm 调用

这个版本应该能显著减少重复更新,提高widget的响应性能和数据一致性。