M5 设计验证:file:// 存储共享真机验证通过 + 文档定稿
验证(临时 VerifyStoragePage 真机跑后已回退): - localStorage:两个不同 file:// 路径(lsA/lsB)+setPathAllowingUniversalAccess 跨页共享 ✓(lsB 读到 lsA 写的值) - cookie:file:// 不支持 WebView cookie;原 Android cookie 全在 native HTTP 层(Volley),WebView 未开 file-scheme cookie, H5 不用 WebView cookie → 非缺口;http(s) cookie 由 WebCookieManager 应用级全局共享 - 结论:采用 file:// + setPathAllowingUniversalAccess + WebCookieManager(全局),无需自定义协议 文档: - 框架新增 §7.5 双 Web 大厅/子游戏架构定稿(结构隔离/激活协议四联动/onInactive 不停JS的平台限制与 appservice 正解/存储验证结论/状态机/改造清单) - 01_WBS:M5 标记"设计就绪",记存储验证通过 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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 任务明细(全部 ☑)**:
|
||||
|
||||
@@ -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. 启动编排与配置/资源子系统
|
||||
|
||||
Reference in New Issue
Block a user