当前 TTMusic 的音乐卡片播放控制没有完全独立:
play_pause/prev/next/seek_to 当前优先走 call 到 EntryAbilitycall 的接收方不存在,按钮无响应FormExtensionAbility 当前只能把事件转发给 eventHub,或兜底拉起 EntryAbilityEntryAbility 冷启动兜底,就会把应用前台界面拉起,不符合目标用户目标已经明确:
播放/暂停/上一首/下一首 仍然可用根据用户提供的鸿蒙官方文档《卡片拉起应用UIAbility到后台(call事件)》:
postCardAction(... action: 'call') 可以将指定 UIAbility 拉到后台call 事件支持指定方法名和参数ohos.permission.KEEP_BACKGROUND_RUNNINGohos.permission.START_INVISIBLE_ABILITY这意味着本项目不必走 AppServiceExtensionAbility 或 invisible ability 路线,可以直接采用:
卡片 -> call -> 后台 UIAbility -> 独立播放控制入口
EntryAbilityTTMusic 当前卡片控制动作的接收方是 EntryAbility.callee。这在应用存活时可用,但在进程被强杀后没有稳定的后台控制入口。
FormAbility 不能直接控播MusicCardFormAbility 当前只负责:
eventHubEntryAbility它不是实际的冷启动控播执行者。
当前播放能力虽然已经在做拆分,但仍然与页面侧运行态、页面事件和 LocalMusic 生命周期耦合较深。结果是:
本次改造只解决音乐卡片后台控播,不做无关重构。
成功标准:
播放/暂停/上一首/下一首/进度跳转 可正常工作播放/暂停/上一首/下一首 可直接生效UIAbility路径:
卡片 -> call -> 后台控播 UIAbility -> 独立播放控制器
优点:
START_INVISIBLE_ABILITY缺点:
FormAbility.message路径:
卡片 -> message -> FormAbility -> 独立播放控制器
优点:
FormAbility缺点:
UIAbility 执行 call”路径不一致FormAbility 已经承担卡片数据职责,再承担后台播放器宿主会混杂两类生命周期EntryAbility路径:
卡片 -> call/router -> EntryAbility -> 播放控制器
优点:
缺点:
采用方案 A。
具体做法:
call 的 UIAbilityUIAbility 不负责页面展示,只负责注册 callee.on(...)播放/暂停/上一首/下一首/进度跳转 全部发送到这个后台控播 UIAbilityrouter 到 EntryAbilityLocalMusic 页面实例play_pause -> call -> MusicCardControlAbilityprev_song -> call -> MusicCardControlAbilitynext_song -> call -> MusicCardControlAbilityseek_to -> call -> MusicCardControlAbilityopen_player -> router -> EntryAbility新增后台控播宿主后,它需要负责:
call 方法和参数play/pause/prev/next/seekLocalMusic 和页面运行态继续负责:
页面侧不再承担“卡片强杀后冷启动时的唯一执行入口”。
UIAbility建议新增单独能力,例如:
MusicCardControlAbility职责:
onCreate 中注册 callee.on(MusicCardActionConstants.CALL_METHOD_HANDLE_ACTION, ...)callee.off(...)该能力在 module.json5 中新增 abilities 配置。
EntryAbility所有卡片页面中的控制按钮都改成:
abilityName: 'MusicCardControlAbility'action: 'call'只有“打开播放器”保留:
abilityName: 'EntryAbility'action: 'router'建议新增一个面向后台卡片控播的控制器,例如:
MusicCardBackgroundPlaybackController职责:
toggle/previous/next/seekToMusicCardManager.updateAllForms(...)该控制器的目标不是替代现有前台控制器,而是提供“无页面实例时也能运行”的最小控播闭环。
后台控播所需的数据优先来自现有持久化层:
如果快照存在但队列缺失:
play_pause 至少应支持恢复当前歌曲prev/next 在没有有效队列时退化为保持当前歌曲不切换,并记录日志最终控制接口应统一为:
UIAbility 也调用同一组控制方法这样可以避免出现两套播放切换逻辑不一致的问题。
play_pause 不做前台拉起,只记录日志prev/next 不做前台拉起,只记录日志seek_to 参数非法时忽略新增或补充以下测试:
EntryAbility 的路由测试播放/暂停/上一首/下一首 正常UIAbility 配置与空实现call 目标切换到新能力本次不处理: