uni-app App端不支持OS级多窗口,所谓“多任务并发”实为后台异步操作并行,需通过固定槽位+任务队列模型控制下载/上传并发数(建议3–5),配合独立tempFilePath、原生存储状态、唯一任务ID及系统权限保障稳定性。

uni-app 在 App 端原生不支持「应用内多窗口」意义上的并发任务隔离(比如像桌面端那样开多个独立窗口进程),所谓“多窗口”实际是单 Activity/ViewController 容器下的页面栈或视图层切换,真正的并发需靠任务调度模型而非窗口机制。
App 端所谓“多窗口”本质是页面栈 + 视图复用,不是 OS 级多窗口
uni-app 的 App 端(iOS/Android)运行在单一原生容器中:uni-app 页面切换走的是 uni.navigateTo / uni.switchTab,底层对应 Android 的 Activity 栈或 iOS 的 ViewController 层级。它没有真正意义上的多窗口(如 HarmonyOS 的 PiPWindow 或 Windows 的多窗口实例)。所谓“多任务并发”,实际指:多个下载、上传、定时任务、WebSocket 连接等**后台异步操作并行执行**,而非 UI 多窗口并存。
- manifest.json 中配置
"multitask": true仅影响分屏/画中画等系统级能力,对 JS 任务调度无作用 - pages.json 的
subNVue是轻量级原生子视图,但共享主线程,不能脱离主 WebView 执行独立 JS 逻辑 - 鸿蒙 NEXT 或 HarmonyOS 平台可通过
@ohos.ability.WindowStage创建多窗口,但需 UTS 原生插件桥接,uni-app标准 JS 层不可直接调用
真正的并发处理必须靠 JS 层任务队列 + 限流控制
App 端的并发瓶颈不在 UI 层,而在原生请求层(uni.request、uni.downloadFile、uni.uploadFile)——它们受系统 HTTP 连接池限制(通常 iOS WKWebView ≤6,Android X5 ≤10)。直接 Promise.all 或 for 循环触发,会导致静默丢弃、undefined 结果、Network 无记录。
- 下载任务:必须用「固定槽位 + 队列」模型,例如最多同时跑
3个uni.downloadFile,每个配独立tempFilePath - 上传任务:同理,
uni.uploadFile并发数建议 ≤3,避免 AndroidOutOfMemoryError或 iOS 文件句柄耗尽 - 网络请求:用
p-limit封装uni.request,或手写批处理函数,如runInLimit(requests, 6) - 注意:所有任务 ID 必须唯一(推荐用
URL + timestamphash),否则onProgressUpdate或 success 回调容易错乱
任务状态持久化与跨生命周期存活的关键点
App 端任务一旦退到后台,JS 线程可能被暂停或销毁,但原生下载/上传任务仍可继续(取决于系统策略)。若想让任务“看起来一直在跑”,必须把状态存在原生侧或本地可靠存储中,不能只靠 Vue data。
-
tempFilePath不可靠:iOS 可能在内存紧张时被系统清理;Android 在重启后路径失效 —— 下载完成必须立刻uni.saveFile到uni.env.USER_DATA_PATH或plus.io.convertLocalFileSystemURL持久路径 - 任务元数据(url、state、progress)应存入
uni.setStorageSync或 SQLite(通过uni-sqlite插件),避免页面重进丢失上下文 - 监听
app.vue的onShow,恢复任务列表并轮询原生插件状态(如zhimi-downloadManager.allDownloadsCallback),不要依赖 onLaunch - Android 上需声明
android.permission.POST_NOTIFICATIONS和foregroundService类型,否则后台下载可能被系统 kill
真正难的不是“怎么开多个窗口”,而是让多个长期运行的任务在 App 生命周期断裂时仍能恢复状态、不丢进度、不冲突路径——这需要 JS 调度 + 原生存储 + 系统权限三者咬合,缺一不可。


















