唯一可靠方式是通过App.vue中的onShow/onHide钩子维护isAppForeground标识:onShow设为true,onHide设为false;其他API如uni.getSystemInfoSync().platform仅返回平台信息,无法反映运行时前后台状态。

uni-app 里没有运行时 API 能实时、准确判断“当前应用是否在前台”,唯一可靠的方式是靠 onShow 和 onHide 生命周期钩子的状态推断。
onShow / onHide 是唯一可依赖的信号源
这两个钩子只在 App.vue 中有效,且是 App 端(iOS/Android)前后台切换时**唯一稳定触发**的 JS 层回调:
-
onShow触发 = 应用已进入前台(包括冷启动、热切回、从通知栏打开等所有场景) -
onHide触发 = 应用已进入后台(按 Home 键、切应用、锁屏等),但不表示进程被杀 - 它们之间的时间窗口,就是你主观认定的“前台运行期”;一旦
onHide触发,就该认为应用已不在前台 - 别在页面或组件里写这两个钩子——写了也监听不到应用级状态
为什么不能用 uni.getSystemInfoSync().platform 或 $mp.platform 判断前台/后台
这些 API 返回的是**构建目标平台或设备底层信息**,和应用当前是否活跃完全无关:
-
uni.getSystemInfoSync().platform在微信小程序真机上可能返回"android",H5 下返回"web",鸿蒙可能为空——它根本不反映“前台/后台”状态 -
$mp.platform是非标准全局变量,H5 环境常为undefined,App 平台不提供,且只在编译时静态存在,无法响应运行时状态变化 - 任何基于
UNI_PLATFORM或process.env的判断,都只能用于条件编译分发逻辑,不能用于运行时状态检测
如何安全地维护“前台/后台”状态标识
你需要自己维护一个布尔标记,并严格绑定到生命周期钩子:
- 在
App.vue的data中定义isAppForeground: true - 在
onShow中设为true,并在此校验网络、登录态、重连原生模块(如蓝牙、定位) - 在
onHide中立即设为false,并清除setInterval、暂停视频、保存草稿到uni.setStorageSync - 不要依赖定时器轮询去“探测”前台状态——iOS 后台 JS 执行权极不可靠,
setTimeout在 iOS 15+ 上几十秒内大概率被挂起
安卓保活 ≠ 前台状态可测
即使你通过原生插件启用了前台服务、申请了电池优化白名单,也无法让 JS 层获得“应用正在前台”的实时反馈:
- 前台服务只影响系统是否回收进程,不改变
onHide的触发时机或行为 - 所有“判断其他 App 是否在前台”的 Android 原生方法(如
UsageStatsManager、无障碍服务)都需要用户授权,且无法在 uni-app JS 层直接调用 - 试图用
plus.runtime.getProperty或getRunningAppProcesses拿前台包名,属于原生开发范畴,uni-app 默认不暴露这类能力
真正容易被忽略的是:你维护的这个 isAppForeground 标识,只在 JS 上下文存活期间有效。一旦系统回收进程(低内存 Android、iOS 长时间后台),下次 onShow 触发时,整个 Vue 实例已重建,必须重新初始化状态,不能假设上次的 data 还在。


















