M5(T-M5-04): onRenderExited 渲染崩溃兜底

- 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) <noreply@anthropic.com>
This commit is contained in:
lanterngamescn
2026-06-25 23:52:42 +08:00
parent 9abd571f43
commit 1aa1ccf9af
2 changed files with 19 additions and 0 deletions
@@ -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%')
+17
View File
@@ -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();