收藏功能修复验证.md 4.6 KB

收藏功能修复验证

问题描述

根据日志分析,发现收藏歌曲列表获取总数为空的问题:

UnifiedPlayerService: 当前歌曲为空 - favList:[]

虽然实际上是有收藏歌曲的,但系统播控中心显示的收藏状态始终为 isFavorite: false

问题根因分析

1. 异步数据加载问题

UnifiedPlayerService.getFav() 方法存在异步处理问题:

  • 方法立即返回 this.favList(可能为空)
  • 数据库查询是异步的,但方法不等待查询完成
  • 导致 getCurrentSongFavoriteState() 总是获取到空的收藏列表

2. 竞态条件问题

LocalMusic.doFav() 方法中:

  • 调用 unifiedPlayerService.updateFavoriteList() 更新收藏列表
  • 然后手动更新 AVSession 的收藏状态
  • 这与 UnifiedPlayerService 自己的 AVSession 更新产生竞态条件

修复方案

1. 优化收藏列表获取逻辑

文件: entry/src/main/ets/common/service/UnifiedPlayerService.ets

getFav(): Array<VideoItem>{
  if (this.favList.length>0){
    console.log("Heanup UnifiedPlayerService favList cached:"+json.stringify( this.favList));
    return this.favList;
  }
  // 如果缓存为空,异步更新但返回空数组,避免阻塞
  this.getTable().queryByisFav(1, async (result: VideoItem[]) => {
    console.log("Heanup UnifiedPlayerService favList:"+json.stringify( result));
    this.favList = result;
    // 更新收藏列表后,重新更新AVSession状态以反映正确的收藏状态
    if (result.length > 0) {
      setTimeout(() => {
        this.updateSessionPlayState();
      }, 100);
    }
  })
  return this.favList;
}

2. 改进收藏状态检查逻辑

private getCurrentSongFavoriteState(): boolean {
  try {
    let currentSong = this.playlistModel.getCurrentSong();
    if (!currentSong) {
      LogUtils.getInstance().LOGI(`UnifiedPlayerService: 当前歌曲为空`);
      return false;
    }
    
    let favList = this.getFav();
    if (!favList || favList.length === 0) {
      // 如果收藏列表为空,可能还在加载中,先返回false
      // 但不记录为错误,因为这是正常的初始化状态
      return false;
    }
    
    // 检查当前歌曲是否在收藏列表中
    for (let i = 0; i < favList.length; i++) {
      if (favList[i].filePath === currentSong.filePath && favList[i].isFav === 1) {
        LogUtils.getInstance().LOGI(`UnifiedPlayerService: 收藏歌曲:${currentSong.filePath}`);
        return true;
      }
    }
    LogUtils.getInstance().LOGI(`UnifiedPlayerService: 未收藏歌曲:${currentSong.filePath}`);
    return false;
  } catch (error) {
    LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to get favorite state: ${error}`);
    return false;
  }
}

3. 添加收藏状态刷新方法

/**
 * 强制刷新收藏状态(用于收藏/取消收藏操作后)
 */
public async refreshFavoriteStatus(): Promise<void> {
  try {
    // 清空缓存,强制重新加载
    this.favList = [];
    await this.updateFavoriteList();
    LogUtils.getInstance().LOGI('UnifiedPlayerService: Favorite status refreshed');
  } catch (error) {
    LogUtils.getInstance().LOGI(`UnifiedPlayerService: Failed to refresh favorite status: ${error}`);
  }
}

4. 优化收藏操作处理

文件: entry/src/main/ets/view/LocalMusic.ets

将原来的手动 AVSession 更新替换为统一的刷新方法:

// 刷新UnifiedPlayerService的收藏状态,这会自动更新AVSession
await this.unifiedPlayerService.refreshFavoriteStatus();

5. 并行初始化收藏列表

在服务初始化时并行加载收藏列表:

// 并行初始化收藏列表和恢复数据,提高效率
const initPromises2 = [
  this.restorePersistedState(),
  this.initializeFavoriteList()
];

await Promise.all(initPromises2);

预期效果

修复后应该能够:

  1. 正确加载收藏歌曲列表
  2. 在系统播控中心正确显示收藏状态
  3. 收藏/取消收藏操作后立即更新播控状态
  4. 避免竞态条件和重复的 AVSession 更新

验证方法

  1. 启动应用,播放一首已收藏的歌曲
  2. 检查系统播控中心是否显示心形图标(收藏状态)
  3. 在应用中取消收藏,检查播控中心是否立即更新
  4. 重新收藏,检查播控中心是否立即显示收藏状态
  5. 查看日志,确认不再出现 "当前歌曲为空 - favList:[]" 的错误信息

相关文件

  • entry/src/main/ets/common/service/UnifiedPlayerService.ets
  • entry/src/main/ets/view/LocalMusic.ets
  • entry/src/main/ets/common/util/MediaTable.ets