# 收藏功能修复验证 ## 问题描述 根据日志分析,发现收藏歌曲列表获取总数为空的问题: ``` 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` ```typescript getFav(): Array{ 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. 改进收藏状态检查逻辑 ```typescript 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. 添加收藏状态刷新方法 ```typescript /** * 强制刷新收藏状态(用于收藏/取消收藏操作后) */ public async refreshFavoriteStatus(): Promise { 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 更新替换为统一的刷新方法: ```typescript // 刷新UnifiedPlayerService的收藏状态,这会自动更新AVSession await this.unifiedPlayerService.refreshFavoriteStatus(); ``` ### 5. 并行初始化收藏列表 在服务初始化时并行加载收藏列表: ```typescript // 并行初始化收藏列表和恢复数据,提高效率 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`