app端监听多任务切换应将onhide/onshow逻辑写在app.vue中,仅应用级可靠触发;onlaunch不等于启动完成,依赖plus或系统信息的逻辑需延迟至onshow首次触发时执行。

App端如何监听多任务切换(onHide/onShow)
uni-app 在 App 端(iOS/Android 原生容器)确实能响应多任务切换,但必须明确:只有 onHide 和 onShow 两个生命周期钩子生效,且仅在「应用级」而非页面级可靠触发——页面级的 onHide/onShow 在 App 端基本不可靠,别依赖。
实操要点:
- 把监听逻辑写在
App.vue的onHide/onShow中,不是页面或组件里 - Android 上切到后台再切回,
onShow一般能触发;iOS 上从多任务卡片切回时也基本稳定,但「从锁屏唤醒」或「通知中心下拉后返回」可能不触发onShow(系统限制,非 bug) - 不要在
onHide里执行耗时操作(如上传日志、清理缓存),它可能被系统快速中断;建议只做标记(如this.appHidden = true)或发轻量事件 - 若需区分「切后台」和「完全退出」,可结合
plus.runtime.getProperty('state')(需 HBuilderX 3.1.22+)判断当前是否为后台运行态
为什么 onLaunch 不等于 App 启动完成
onLaunch 在 App 进程创建后立即执行,此时原生容器尚未就绪,uni.getSystemInfoSync() 可能返回空值,plus.navigator 等 API 尚未可用。这不是 uni-app 的问题,而是原生引擎加载时序决定的。
安全做法:
- 所有依赖
plus或需要完整系统信息的逻辑,延迟到onShow首次触发时再执行(此时原生层已 ready) - 或用
uni.getSystemInfo+Promise轮询,直到platform字段存在(避免死等) -
onLaunch适合做纯 JS 初始化(如全局 store setup、埋点 SDK 初始化),但不要调用任何uni.或plus.异步 API
App.vue 生命周期与 pages.json 的关系
App.vue 的生命周期不受 pages.json 中 subNVue、tabBar 或预加载配置影响,但它会受「启动模式」干扰:如果 App 被系统以「冷启动」方式唤起(如点击推送消息),onLaunch 必定触发;但如果用户从最近任务列表点击图标切回(热启动),则只触发 onShow,onLaunch 不会重复执行。
关键细节:
-
onLaunch参数options里的scene字段,在 App 端始终为1001(默认场景),不能用于区分来源;真要识别唤起渠道,得用plus.push.getClientInfo()或自定义 scheme 参数 - 若开启
pages.json中的"nvueStyle": true,部分生命周期(如onPageScroll)行为会变化,但onHide/onShow不受影响 - 使用自定义基座调试时,
onHide可能因基座保活机制延迟触发,真机测试才准确
Android 后台进程被杀导致 onShow 失效怎么办
Android 系统内存紧张时会直接杀死 WebView 进程,此时 App 再次切回相当于冷启动,onShow 不会触发,而是走 onLaunch → onShow 流程。这意味着你无法通过 onShow 恢复上一次的页面状态。
可行方案:
- 页面状态持久化不能只靠内存变量,关键数据必须存到
uni.setStorageSync或plus.storage(后者支持跨进程读写) - 在
onHide中主动保存必要现场(如当前页面路径、滚动位置、表单草稿),并在onShow或页面onLoad时检查并恢复 - 避免在
onShow中做「重连 WebSocket」这类强依赖网络的操作——它可能比页面渲染还慢,导致 UI 卡顿或重复连接
最易被忽略的一点:iOS 的后台运行时间上限是 30 秒(非 VoIP/定位等特殊后台模式),超过后系统会挂起进程,onHide 已触发,但你没机会在挂起前完成清理,所以所有异步清理操作都得设超时兜底。











