锁屏时音频卡顿的根本原因是误用uni.createInnerAudioContext(),应改用uni.getBackgroundAudioManager()并严格配置manifest.json及初始化顺序。

锁屏时音频卡顿,根本不是播放逻辑写得不够“顺”,而是你用错了 API —— uni.createInnerAudioContext() 在锁屏/后台下大概率被系统静默终止,iOS 尤其明显。真正在锁屏后稳定播、不卡、能控制的,只有 uni.getBackgroundAudioManager(),且必须满足平台级硬性条件。
为什么 uni.createInnerAudioContext() 锁屏必卡
这个 API 本质是前台音频上下文,设计目标就是“页面可见时播放”。锁屏瞬间,iOS 系统直接挂起音频会话,Android 厂商(华为 EMUI、小米 MIUI)也会因省电策略强制暂停或 kill 进程。此时你看到的“卡顿”,其实是播放已中断,但 JS 层没收到任何回调(onStop、onError 都可能失灵)。
- 微信小程序里,切后台后
onHide触发时,innerAudioContext实例已不可用,再调play()或seek()会静默失败 - H5 和 App 端虽不强制中断,但若未启用后台音频能力,锁屏后 WebView 可能被系统休眠,导致定时器延迟、事件响应滞后
- 试图用
setInterval轮询audio.playing状态来“抢救”,在锁屏下基本无效——JS 执行本身就被降频甚至冻结
uni.getBackgroundAudioManager() 必须配 manifest.json
只写 JS 不配原生权限,等于没开后台音频的门。manifest.json 的配置必须精确到字段层级,错一个就白搭:
- iOS 必须在
app-plus → distribute → ios → UIBackgroundModes下填["audio"],漏掉引号或写成audio(无数组)都不生效 - Android 需在
app-plus → distribute → android → permissions中显式声明"android.permission.WAKE_LOCK",否则部分机型锁屏 3–5 秒即停 - 两个平台配置不能混写在同一级,比如把
UIBackgroundModes写在android节点下,云打包会忽略
改完 manifest 后必须重新「云打包」,本地调试器和热更新无法触发后台音频能力。
锁屏不卡的关键初始化顺序
顺序错一步,锁屏后就无声或控件不显示。以下三步缺一不可,且必须严格按序执行:
- 先赋值
manager.src(必须是 HTTPS URL,本地路径在 iOS 微信和部分 Android 上失效) - 再设置元信息:
manager.title、manager.singer、manager.coverImgUrl至少填三项中的两项(iOS 锁屏界面才显示控件) - 最后调用
manager.play()—— 只设src不play(),后台会话不会激活
常见错误:在 onLoad 里只设了 src,等用户点击按钮才 play(),此时锁屏后已失去焦点,再 play() 无效。
Android 厂商适配要防“假播放”
即使配置全对,华为、小米等机型仍可能因系统级省电策略,在锁屏后几秒内自动暂停。这不是代码 bug,而是需主动保活:
- 不要依赖
onPlay后就“万事大吉”,加个setInterval每 10 秒检查manager.playing,若为false且manager.paused === false,说明被系统强停,立即重试manager.play() - 避免频繁切换
src:每次换歌都manager.src = newUrl+manager.play(),在低端机上易触发缓冲卡顿;建议预加载新音频到new Audio(newUrl),确认oncanplay后再替换 manager - 慎用
manager.seek():锁屏状态下部分机型 seek 失败率高,如需跳转,优先用manager.pause()+manager.play()组合模拟“软跳转”
最常被忽略的一点:所有音频操作必须在用户手势(如 onClick)后首次触发,否则 iOS Safari 和部分 Android WebView 会拒绝激活音频会话,导致锁屏后彻底无声——哪怕 manifest 和代码全对。











