chendeben 1 год назад
Родитель
Сommit
539e7d8174
1 измененных файлов с 53 добавлено и 63 удалено
  1. 53 63
      entry/src/main/ets/common/service/UnifiedPlayerService.ets

+ 53 - 63
entry/src/main/ets/common/service/UnifiedPlayerService.ets

@@ -449,6 +449,7 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
   private imageCacheDir: string = ''; // 图片缓存目录
   private readonly CACHE_EXPIRY_DAYS: number = 7; // 缓存有效期:7天
   private readonly MAX_CACHE_SIZE_MB: number = 50; // 最大缓存大小:50MB
+  private hasChecked: boolean=false;
 
   private constructor() {
     this.playerManager = PlayerManager.getInstance();
@@ -975,10 +976,10 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
 
       // 2. 检查服务是否已准备就绪
       if (!this.isAllServicesReady()) {
-        LogUtils.getInstance().LOGI(`UnifiedPlayerService: ${direction} - 服务未就绪,等待服务初始化完成`);
+        LogUtils.getInstance().LOGI(`Heanup UnifiedPlayerService: ${direction} - 服务未就绪,等待服务初始化完成`);
         const isReady = await this.waitForAllServicesReady(500, false);
         if (!isReady) {
-          LogUtils.getInstance().LOGI(`UnifiedPlayerService: Services not ready for ${direction}, skipping`);
+          LogUtils.getInstance().LOGI(`Heanup UnifiedPlayerService: Services not ready for ${direction}, skipping`);
           // 统一处理方式:在服务未就绪时直接返回,避免抛出错误中断用户体验
           this.isManualSongChange = false;
           return;
@@ -1306,38 +1307,44 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
    * 用于桌面卡片控制等场景,确保在执行播放控制前服务状态正常
    */
   isAllServicesReady(): boolean {
-    try {
-      // 检查基本初始化状态
-      if (!this.isInitialized) {
-        LogUtils.getInstance().LOGI('UnifiedPlayerService: Service not initialized');
-        return false;
-      }
+    if (this.hasChecked){
+      return true;
+    }else {
+      this.hasChecked = true;
+      try {
+        // 检查基本初始化状态
+        if (!this.isInitialized) {
+          LogUtils.getInstance().LOGI('UnifiedPlayerService: Service not initialized');
+          return false;
+        }
 
-      // 检查核心组件是否就绪
-      if (!this.playerManager || !this.stateModel || !this.playlistModel) {
-        LogUtils.getInstance().LOGI('UnifiedPlayerService: Core components not ready');
-        return false;
-      }
+        // 检查核心组件是否就绪
+        if (!this.playerManager || !this.stateModel || !this.playlistModel) {
+          LogUtils.getInstance().LOGI('UnifiedPlayerService: Core components not ready');
+          return false;
+        }
 
-      // 检查 PlayerManager 是否已经初始化
-      const playerInstance = this.playerManager.getIjkPlayer();
-      if (!playerInstance) {
-        LogUtils.getInstance().LOGI('UnifiedPlayerService: Player instance not ready');
-        return false;
-      }
+        // 检查 PlayerManager 是否已经初始化
+        const playerInstance = this.playerManager.getIjkPlayer();
+        if (!playerInstance) {
+          LogUtils.getInstance().LOGI('UnifiedPlayerService: Player instance not ready');
+          return false;
+        }
 
-      // 检查上下文是否可用
-      if (!this.context) {
-        LogUtils.getInstance().LOGI('UnifiedPlayerService: Context not available');
+        // 检查上下文是否可用
+        if (!this.context) {
+          LogUtils.getInstance().LOGI('UnifiedPlayerService: Context not available');
+          return false;
+        }
+
+        LogUtils.getInstance().LOGI('UnifiedPlayerService: All services ready');
+        return true;
+      } catch (error) {
+        LogUtils.getInstance().LOGI(`UnifiedPlayerService: Service readiness check failed: ${error}`);
         return false;
       }
-
-      LogUtils.getInstance().LOGI('UnifiedPlayerService: All services ready');
-      return true;
-    } catch (error) {
-      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Service readiness check failed: ${error}`);
-      return false;
     }
+
   }
 
   /**
@@ -2486,12 +2493,12 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
       } else {
         // 向后兼容的旧逻辑:根据播放器实际状态切换
         LogUtils.getInstance().LOGI('UnifiedPlayerService: widgetIsPlaying not provided, using fallback logic.');
-        const isActuallyPlaying = this.getActualPlayingState();
-        if (isActuallyPlaying) {
-          await this.pause();
-        } else {
-          await this.startPlayOrResumePlay();
-        }
+      const isActuallyPlaying = this.getActualPlayingState();
+      if (isActuallyPlaying) {
+        await this.pause();
+      } else {
+        await this.startPlayOrResumePlay();
+      }
       }
     } catch (error) {
       LogUtils.getInstance().LOGI(`UnifiedPlayerService onPlayPause error: ${error}`);
@@ -2974,44 +2981,27 @@ export class UnifiedPlayerService implements IPlayerService, PlaylistSyncListene
         return;
       }
 
-      // --- 两阶段更新策略 ---
-      // 阶段一:立即更新UI状态(文本、图标等),不包含封面图,确保响应速度
-      const dataWithoutImage = await this.getWidgetFormData(false); // false: 不加载图片
-      if (!dataWithoutImage) {
-        LogUtils.getInstance().LOGI('UnifiedPlayerService updateAllForms: Failed to get widget data for phase 1.');
+      // --- 单阶段更新策略 ---
+      // 直接获取包含所有数据的卡片信息,包括图片。
+      // 图片加载有缓存机制,对于已加载过的歌曲,此操作很快。
+      // 这可以避免双阶段更新导致的UI闪烁问题(例如背景色先变默认再变主色调)。
+      const widgetData = await this.getWidgetFormData(true); // true: 加载图片
+      if (!widgetData) {
+        LogUtils.getInstance().LOGI('UnifiedPlayerService updateAllForms: Failed to get widget data.');
         return;
       }
 
-      const formBindingDataWithoutImage = formBindingData.createFormBindingData(dataWithoutImage);
+      const bindingData = formBindingData.createFormBindingData(widgetData);
       // 并行更新所有卡片,提高效率
-      const updatePromisesPhase1 = formInfoList.map(formInfo =>
-        formProvider.updateForm(formInfo.formId, formBindingDataWithoutImage)
+      const updatePromises = formInfoList.map(formInfo =>
+        formProvider.updateForm(formInfo.formId, bindingData)
       );
-      await Promise.all(updatePromisesPhase1);
-      LogUtils.getInstance().LOGI(`UnifiedPlayerService: Phase 1 (quick update) completed for ${formInfoList.length} forms.`);
-
-      // 阶段二:异步加载封面图,然后再次更新卡片
-      // 使用 setTimeout(0) 将其推到事件循环的下一个tick,避免阻塞当前流程
-      setTimeout(async () => {
-        const dataWithImage = await this.getWidgetFormData(true); // true: 加载图片(这步可能很慢)
-        if (!dataWithImage || Object.keys(dataWithImage.formImages).length === 0) {
-          LogUtils.getInstance().LOGI('UnifiedPlayerService: No image to update in Phase 2.');
-          return; // 没有图片或加载失败,则无需第二阶段更新
-        }
-
-        const formBindingDataWithImage = formBindingData.createFormBindingData(dataWithImage);
-        const updatePromisesPhase2 = formInfoList.map(formInfo =>
-          formProvider.updateForm(formInfo.formId, formBindingDataWithImage)
-        );
-        await Promise.all(updatePromisesPhase2);
-        LogUtils.getInstance().LOGI(`UnifiedPlayerService: Phase 2 (image update) completed for ${formInfoList.length} forms.`);
-      }, 0);
+      await Promise.all(updatePromises);
+      LogUtils.getInstance().LOGI(`UnifiedPlayerService: All forms updated for ${formInfoList.length} forms.`);
 
     } catch (error) {
       LogUtils.getInstance().LOGI(`UnifiedPlayerService updateAllForms error: ${error}`);
     } finally {
-      // 关键:在阶段一完成后就立即释放标志,允许新的状态更新(不含图片)可以被触发
-      // 阶段二的图片加载在后台进行,不应阻塞后续的状态更新
       this.isUpdatingForms = false;
     }
   }