修复 SwitchOverGameData 解析失败致无法跳转子游戏

H5 对 SwitchOverGameData 的 data 字段直接传 JSON 对象(如 {webtype:3,...})。
Android org.json getString 会把嵌套对象强制转为 JSON 字符串再交 handler JSON.parse;
而 ArkTS JSON.parse 保留为对象,handler 再 JSON.parse(对象) 得到 "[object Object]"
→ Invalid Token、解析失败、不发 SWITCH_GAME、不跳转。

- MessageCodec.toArray:新增 coerceToString,对 data/responseData 复刻 org.json
  getString 语义(对象/数组→紧凑 JSON 串,数字/布尔→字符串)。
- NavProvider:webtype 统一 String() 化,避免下游 `webtype !== '2'` 对数字恒真
  把竖屏子游戏错误强制横屏。

对应契约 §11.1 路径A、§2.4 Message。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
lanterngamescn
2026-06-27 01:55:40 +08:00
co-authored by Claude Opus 4.8
parent 5f3161ee49
commit e75f567948
2 changed files with 26 additions and 3 deletions
@@ -48,12 +48,33 @@ export class MessageCodec {
for (const o of arr) {
const m = new Message();
m.handlerName = o.handlerName;
m.data = o.data;
// data/responseDataH5 可能直接传对象(如 SwitchOverGameData)。Android org.json
// getString 会把嵌套对象强制转成 JSON 字符串,handler 再 JSON.parse;这里复刻该语义,
// 否则对象原样传到 handler 后 JSON.parse(对象) 会得到 "[object Object]" 而解析失败。
m.data = MessageCodec.coerceToString(o.data);
m.callbackId = o.callbackId;
m.responseId = o.responseId;
m.responseData = o.responseData;
m.responseData = MessageCodec.coerceToString(o.responseData);
list.push(m);
}
return list;
}
/**
* 复刻 Android org.json `getString` 对 data/responseData 的取值语义:
* 字符串原样返回;对象/数组转紧凑 JSON 字符串;数字/布尔转其字符串;null/缺省返回 undefined。
*/
private static coerceToString(v: Object | undefined): string | undefined {
if (v === undefined || v === null) {
return undefined;
}
const t: string = typeof v;
if (t === 'string') {
return v as string;
}
if (t === 'object') {
return JSON.stringify(v);
}
return String(v);
}
}
@@ -60,7 +60,9 @@ export class NavProvider implements CapabilityProvider {
this.log.w(`SwitchOverGameData bad json: ${(e as Error).message}`);
return;
}
const payload: SwitchGamePayload = { webtype: req.webtype, dir: req.Gamedirectory, data: req.data };
// webtype 契约为 "2"竖/"3"横,但 H5 可能发数字(如 3)。统一转字符串,
// 否则下游 `webtype !== '2'` 的严格比较对数字恒为真,会把竖屏子游戏错误强制横屏。
const payload: SwitchGamePayload = { webtype: String(req.webtype), dir: req.Gamedirectory, data: req.data };
EventBus.emit(NavEvents.SWITCH_GAME, payload);
}