diff --git a/docs/设计文档/Plan/01_任务分解WBS.md b/docs/设计文档/Plan/01_任务分解WBS.md index b62343a..4578c02 100644 --- a/docs/设计文档/Plan/01_任务分解WBS.md +++ b/docs/设计文档/Plan/01_任务分解WBS.md @@ -17,7 +17,7 @@ | **M2** 容器 + 启动 + 资源 | ☑ 完成 | 13 任务全完成;**V2 真机通过(R-02 关闭)**、VersionResolver 单测覆盖 81.8%;T-M2-12 机制已验证(真实远程大厅待服务端可用时终验) | | **M3** 本期能力 | ◐ 进行中 | 16/17 完成(15 Provider+前后台);T-M3-06 NavProvider 随 M4 完成;余 T-M3-17 真机回归(录音 prepareaudio 待服务端) | | **M4** 通用网页容器 | ☑ 完成 | GenericWebContainer+SettingsProxy(6方法)+getWebdata/gamebackkeydown/backgameData 直调+101回传+返回键;子游戏切换(路径A)/打开通用容器(路径B) | -| **M5** 性能与加固 | ☐ 未开始 | — | +| **M5** 性能与加固 | ◐ 设计就绪 | 双 Web 大厅/子游戏架构定稿(框架 §7.5);**存储共享真机验证通过**(file:// localStorage 跨路径共享;cookie 走 WebCookieManager 全局/H5 不用 WebView cookie);待实现 | | **M6** 暂缓能力集成 | ☐ 未开始 | 按需 | **M0 任务明细(全部 ☑)**: diff --git a/docs/设计文档/TSGame_HarmonyOS框架设计与开发指南.md b/docs/设计文档/TSGame_HarmonyOS框架设计与开发指南.md index 10cf826..8d19a69 100644 --- a/docs/设计文档/TSGame_HarmonyOS框架设计与开发指南.md +++ b/docs/设计文档/TSGame_HarmonyOS框架设计与开发指南.md @@ -564,6 +564,40 @@ H5 以 `file://` 加载并请求本地资源时,ArkWeb 默认按 CORS 拦截 - **实现 API**:运行时 `window.Window.setPreferredOrientation(orientation: window.Orientation)` 动态切换,`window.Orientation` 取 `LANDSCAPE` / `PORTRAIT`(编码前用 `devecocli docs` 核对签名)。 - **要点**:`module.json5` 的 `auto_rotation_landscape` 提供"横屏内跟随传感器旋转(不进竖屏)",运行时 `setPreferredOrientation` 提供"H5 显式切换"——二者叠加既满足横屏项目定位,又守住 H5 零改动。 +### 7.5 双 Web 大厅/子游戏架构(M5 定稿,2026-06-25 验证通过) + +> 复刻原 Android 双 Activity 语义(webviewActivity 大厅 + NewwebviewActivity 子游戏,靠 Activity 生命周期 onPause/onResume 暂停/恢复),在鸿蒙用**单 Ability + 单页内两个 Web 组件**实现——更轻、切换更快、可离屏预热。M2/M4 的单 WebView `loadUrl` 切换是过渡实现,M5 替换之。 + +**结构**:`BridgeGameContainer` 内 `Stack { 大厅Web(常驻) ; if(子游戏!=null) 子游戏Web }`,由 **WebSlotManager** 持两 slot、维护 activeSlot、执行激活协议。每个 slot = 独立 `WebviewController + BridgeController + buildCapabilities()`。子游戏 `SwitchOverGameData` 创建、`backgameData` 销毁(不保活)。大厅常驻无需 NodeController(两 Web 同在一页)。 + +**需求①——大厅/子游戏接口不串(结构隔离)**:每个 Web 一套独立桥 + 能力实例,`BridgeController#L` 只 runJavaScript 到大厅 Web、`#S` 只到子游戏 Web,**物理不可能串**。唯一共享单例(`WeChatApi`)与 EventBus 导航事件由 WebSlotManager **路由到 activeSlot**。 + +**需求②——同时只有一个激活**(激活=联网+渲染+声音+桥接口可执行)。激活协议四联动: + +| 维度 | 激活端 | 非激活端 | +|---|---|---| +| 渲染/动画/定位 | `web.onActive()` + 显示 | `web.onInactive()` + 隐藏 | +| 桥接口 | `bridge.setActive(true)` | `bridge.setActive(false)`:入站忽略、出站抑制 | +| 原生能力监听/播放 | `registrar.forEachForeground()` | `registrar.forEachBackground()`:停传感器/定位/网络监听、停音频 | +| H5 自身联网/心跳/声音 | `callHandler('appservice','1')` | `callHandler('appservice','2')`:H5 按契约自行进入后台态 | + +> ⚠ **平台限制与正解**:ArkWeb `onInactive()` 暂停动画/定位但**不暂停 JS**;能停 JS 定时器的 `pauseAllTimers()` 是**全局**(会停两个 Web,不可用于单 Web)。即鸿蒙**没有"只冻结一个 Web 的 JS/网络"的原生开关**(比 Android WebView.onPause 弱)。正解:原生侧停掉能停的(渲染/能力/桥),**H5 侧用契约现成的 `appservice('2')` 自停网络/声音**——与原 Android 一致、H5 零改动。 + +**需求③——cookie + localStorage 共享(已真机验证)**: +- **localStorage**:✅ **已验证共享**——两个不同 file:// 路径(`filesDir/tsgames/lsA` 与 `/lsB`)+ `setPathAllowingUniversalAccess([filesDir/tsgames])`,一页写、另一页读到同值。故**沿用 file:// 主选**即满足。 +- **cookie**:file:// 页面不支持 WebView cookie(cookie 绑定 http(s) scheme);但原 Android 的 cookie 全在 native HTTP 层(Volley/java.net.CookieManager),**WebView 从未开 file-scheme cookie,H5 不用 WebView cookie**——故非需求缺口。若未来 H5 在 http(s) 用 cookie,`WebCookieManager` 为**应用级全局单例**(所有 Web 组件共享)自动满足。 +- 结论:**采用 file:// + setPathAllowingUniversalAccess + WebCookieManager(全局)**,无需自定义协议。 + +**激活状态机**(WebSlotManager): +``` +进子游戏: deactivate(大厅)[appservice'2'→onInactive→forEachBackground→setActive(false)→隐藏] + → 注入子游戏 app_data(launchtype'1') → 建子游戏 slot → activate(子游戏)[显示→onActive→forEachForeground→setActive(true)→100%时 appservice'1'+setPostUrl] +返回大厅: destroy(子游戏)[forEachBackground→bridge.dispose→销毁 Web] → activate(大厅)[显示→onActive→forEachForeground→setActive(true)→appservice'1'+getWebdata(data)] +App 前后台: 只对 activeSlot 下发 appservice +``` + +**改造清单**:新增 `WebSlotManager`(entry);`BridgeController` 加 `setActive()`;`BridgeGameContainer` 改 Stack 双 Web、SWITCH_GAME/BACK_GAME 走 SlotManager;Provider 落实 `onForeground/onBackground`(Shake/Location/Network 停起监听、Audio 停起播放);`WeChatApi` resp 路由到 activeSlot。 + --- ## 8. 启动编排与配置/资源子系统