From 1aa1ccf9affa39dc338f7c25974b5e6dc8d7052c Mon Sep 17 00:00:00 2001 From: lanterngamescn Date: Thu, 25 Jun 2026 23:52:42 +0800 Subject: [PATCH] =?UTF-8?q?M5(T-M5-04):=20onRenderExited=20=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E5=B4=A9=E6=BA=83=E5=85=9C=E5=BA=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - WebSlot.onRenderExited(reason):渲染子进程异常退出(崩溃/被杀/OOM)时 controller.refresh() 重载恢复, 重置 firstDone 使重载后重推 appservice/setPostUrl;disposed 守卫避免子游戏销毁期误刷 - BridgeGameContainer:大厅 Web 与子游戏 Web 各挂 .onRenderExited → 对应 slot 恢复 - 防渲染子进程崩溃白屏(框架 §9 内存/崩溃兜底、附录 B 渲染兜底) devecocli build 通过。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/main/ets/pages/BridgeGameContainer.ets | 2 ++ entry/src/main/ets/web/WebSlot.ets | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/entry/src/main/ets/pages/BridgeGameContainer.ets b/entry/src/main/ets/pages/BridgeGameContainer.ets index d59bdbc..c9325d8 100644 --- a/entry/src/main/ets/pages/BridgeGameContainer.ets +++ b/entry/src/main/ets/pages/BridgeGameContainer.ets @@ -189,6 +189,7 @@ export struct BridgeGameContainer { this.slotL?.onFirstProgress(); } }) + .onRenderExited((event: OnRenderExitedEvent) => this.slotL?.onRenderExited(event.renderExitReason)) // 子游戏 Web(临时,subgameUrl 非空时存在) if (this.subgameUrl !== '') { @@ -206,6 +207,7 @@ export struct BridgeGameContainer { this.slotS?.onFirstProgress(); } }) + .onRenderExited((event: OnRenderExitedEvent) => this.slotS?.onRenderExited(event.renderExitReason)) } } .width('100%').height('100%') diff --git a/entry/src/main/ets/web/WebSlot.ets b/entry/src/main/ets/web/WebSlot.ets index fc28a67..a7d5530 100644 --- a/entry/src/main/ets/web/WebSlot.ets +++ b/entry/src/main/ets/web/WebSlot.ets @@ -28,6 +28,7 @@ export class WebSlot { private registrar: CapabilityRegistrar | undefined = undefined; private firstDone: boolean = false; private active: boolean; + private disposed: boolean = false; constructor(role: string, controller: webview.WebviewController, active: boolean, uploadServer: LocalUploadServer) { this.role = role; @@ -82,6 +83,21 @@ export class WebSlot { this.bridgeCtrl?.onPageEnd(); } + /** 渲染子进程退出(崩溃/被杀/OOM):重载本 Web 恢复,防白屏(T-M5-04)。 + * 销毁中(子游戏被移除)不重载。重置 firstDone 使重载后重推 appservice/setPostUrl。 */ + onRenderExited(reason: number): void { + if (this.disposed) { + return; + } + WebSlot.log.w(`[${this.role}] render exited (reason=${reason}); reloading`); + this.firstDone = false; + try { + this.controller.refresh(); + } catch (e) { + WebSlot.log.e(`[${this.role}] refresh after render exit failed: ${(e as BusinessError).message}`); + } + } + /** 页面首次 100%:下发 appservice('1') + setPostUrl(+ 返回大厅待发 getWebdata)。 */ onFirstProgress(): void { if (this.firstDone) { @@ -142,6 +158,7 @@ export class WebSlot { /** 销毁(子游戏返回大厅时)。 */ dispose(): void { + this.disposed = true; this.registrar?.destroyAll(); this.bridgeCtrl?.dispose(); this.adapter?.dispose();