FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat: 完善安卓端返回键处理与退出逻辑 by Shomi-FJS · Pull Request #28 · SPlayer-Dev/SPlayer-for-Android · GitHub

feat: 完善安卓端返回键处理与退出逻辑 - #28

Merged
Re-BeiChen merged 1 commit into
SPlayer-Dev:devfrom
Shomi-FJS:Webview-FIX
May 28, 2026
Merged

feat: 完善安卓端返回键处理与退出逻辑#28
Re-BeiChen merged 1 commit into
SPlayer-Dev:devfrom
Shomi-FJS:Webview-FIX

Conversation

Copy link
Copy Markdown

📌 变更类型

  • ✨ feat — 新功能
  • 🐞 fix — Bug 修复
  • 🎨 style — 仅样式 / 格式,不影响逻辑
  • ♻️ refactor — 重构,不改变外部行为
  • ⚡ perf — 性能优化
  • 📝 docs — 仅文档
  • 🧪 test — 新增 / 修改测试
  • 🔧 chore — 构建 / 脚本 / 依赖
  • 🚀 ci — 仅 CI 配置
  • ⏪ revert — 回滚

📝 变更说明

背景

安卓物理返回键此前直接走 CapacitorApp.exitApp(),存在两个体验断层:

  1. 多层 UI 无层级回退:modal、drawer、全屏播放器、右键菜单子级等弹层,按 back 不会逐层关闭,而是直接退出 App
  2. 退出粗暴:exitApp 仅 finish Activity,前台服务(PlaybackService、FloatingLyricService)继续存活,通知栏与桌面歌词残留;缺乏二次确认,误触退出体验差

解决方案

1. 全局 Back 处理栈(useAndroidBack)

  • 新增 pushBackHandler / useBackHandler / useBackClosable 三层 API
  • back 触发时从栈顶向下分发,handler 返回 true 则消费本次按键
  • 异常被 swallow 视为已处理,避免穿透到下层 UI 触发误关 / 误退
  • useBackClosable(showRef, { onBack }):v-model:show 风格弹层一行接入;onBack 钩子支持"消费但不关闭"语义,用于多层级逐层折叠

2. 弹层 / 菜单接入

  • n-modal 全局包装器:Provider.vue 劫持 useModal().create,默认所有 modal 可被 back 关闭,显式 _backable: false 可禁用(如用户协议、登录强制流程)
  • n-drawer / n-dropdown / 自定义弹窗(SongListMenu / CoverMenu / SearchInpMenu)接入 useBackClosable
  • n-dropdown 子菜单两步折叠:按 back 时若检测 .n-dropdown-menu 多于一层,向 document 派发 ArrowLeft 让 naive UI 内部折叠子菜单,第二次 back 才关整个 dropdown

3. 原生退出能力

  • PlaybackManager.shutdownAll():cleanup() → stopService(FloatingLyricService) → stopService(PlaybackService),每段独立 try/catch
  • AndroidNativePlaybackPlugin.shutdownApp():调 shutdownAll → 100ms 后 finishAndRemoveTask + System.exit(0),从最近任务列表移除并强杀进程
  • TS 侧 androidNativePlayback.ts 暴露 shutdownApp(): Promise

4. 退出确认弹窗

  • 根路由按 back 不再直接退出,弹 $dialog.warning 二次确认
  • 单例标志 + onAfterLeave 兜底,连按 back 不重复弹
  • 弹窗自身也接 back 栈(关 dialog 而非退 App)
  • 点【退出】走原生 shutdownApp,失败兜底 CapacitorApp.exitApp

5. 边界修复

  • useOrientationTransition.exit catch 分支强制把 statusStore.isImmersiveFullscreen 置 false,避免异常路径下沉浸式状态残留导致 back 死循环

6. 类型扩展

  • types/global.d.ts 扩展 ExtendedModalOptions 加 _backable?: boolean

🔗 关联 Issue

Closes #

📱 影响范围

  • 🎵 播放引擎 / 音频
  • 📝 歌词 / 桌面歌词
  • 🔔 通知栏 / MediaSession
  • 🌐 在线音乐 (网易云 / Jellyfin / Navidrome / Emby / Subsonic / Last.fm)
  • 🧩 内置 API (nodejs-mobile)
  • 🎨 UI / 主题 / 布局
  • 📦 构建 / 打包 / 签名
  • 📱 Capacitor / 原生 Android 代码
  • 📄 文档 / README

✅ 自检清单

  • 本 PR 目标分支为 dev
  • 本地已执行 pnpm lint 且无 warning
  • 本地已执行 pnpm typecheck 且无报错
  • 已在 至少一台真机 上构建并验证关键路径
  • UI 改动已兼顾 手机竖屏 + 平板横屏 两种布局
  • 新增 / 修改的文案使用中文,与项目整体风格一致
  • 未引入不必要的依赖 / 大体积资源
  • 未修改签名密钥 / CI Secrets 相关文件

🧪 测试方式

A. Back 多层关闭

  1. 进入二级页(如歌单详情)→ 长按歌曲打开右键菜单
  2. 点【更多操作 →】展开子菜单 → 按 back → 子菜单折叠(dropdown 仍开)→ 再按 back → dropdown 整体关闭
  3. 持续按 back 路由逐级回退

B. 退出确认

  1. 根路由(/ 或 /home)按 back → 弹"退出 SPlayer / 确定要退出吗?"
  2. back → 弹窗关闭,App 不退出
  3. 再次根路由按 back → 弹框 → 点【取消】→ 弹窗关,App 不退出

C. 原生退出彻底性(关键)

  1. 重新弹框 → 点【退出】,立刻检查:
    • 通知栏媒体播放通知 ✅ 消失
    • 桌面歌词浮窗(如开启)✅ 消失
    • 最近任务列表 ✅ 无 SPlayer 卡片
    • 系统设置 → 应用 → SPlayer → 运行中服务 ✅ 空

D. 强制弹窗不被 back 误关

  1. 首次启动触发用户协议弹窗 → 按 back → 弹窗保持,提示"请先阅读并同意用户协议"

E. 沉浸式横屏 back

  1. 进入沉浸式横屏播放 → 按 back → 完整 exit 动画回到竖屏,无沉浸式状态残留

💬 其他说明

兼容性风险

  • n-dropdown 子菜单折叠依赖 naive UI 内部 keyboard: true + ArrowLeft 行为,若升级 naive UI 改了快捷键实现需回归
  • finishAndRemoveTask 需 Android 5.0+,项目 minSdk 已满足
  • System.exit(0) 是兜底强杀,第三方 SDK 注册的 cleanup hook 不会执行,目前无相关依赖

已知边界

  • 退出确认弹窗关闭动画(~200ms)期间连按 back 会被静默吞掉,下一次才能再弹,实测无视觉异常
  • _backable: false 的 modal 仍会消费 back 防止穿透,但 modal 本身不关

- 新增安卓端全局返回键处理栈,支持多层UI自定义返回逻辑
- 为多个弹窗、菜单组件添加安卓返回键关闭支持
- 优化用户协议与登录弹窗的返回键拦截逻辑
- 新增app原生退出方法,支持清理服务后安全退出
- 修复异常场景下全屏状态残留问题
- 扩展naive modal类型以支持自定义返回键行为
Re-BeiChen merged commit f0f0a30 into SPlayer-Dev:dev May 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants


Back | FazBrowse Home | New Git URL