跨端: fix(推送客户端) 热启点通知**不跳转** —— 真机实测逼出来的那半(只写格子没人读)

这是"收尾"里**静态判据看不出来**的那一类,只有设备能抓住。

## 实测经过(模拟器,可复核)

只写 `PendingRoute` 的那版(上一个提交 423ff9f):

    aa force-stop → aa start --ps data '{…open_mail…}'   ⇒ render MailDetailDestination ✓ 冷启能跳
    (应用已在运行)aa start --ps data '{…open_mail…}'   ⇒ **0 次**              ✗ 热启不跳

根因:冷启时页面**刚挂载**,`aboutToAppear` 会读那个静态格子;
热启时页面**早就挂载完**了、`aboutToAppear` 不会重跑 ⇒ 格子写得进去、**没人读**。
症状正是"点了通知,App 弹到前台,停在列表页" —— 而这恰恰是推送**最常见**的用法
(App 在后台,用户点通知回来看那封信)。

## 修法:补"事件发生时就交出去"的那条路

`PushService.deliverRoute(route)`:**有人监听就当场交出去,没人监听才留在格子里**。
两条路都要留着,因为两种启动各走一条(冷启没人监听、热启有人监听):

- `EntryAbility.onCreate` / `onNewWant` 都走 `deliverRoute`(两条启动方式共用一条投递路径);
- `CommPage.aboutToAppear` 注册监听、`aboutToDisappear` 摘除
  (不摘会叫醒已销毁的页面);
- 冷启与热启**共用同一个落点** `navigateToRoute`(各写一遍必然漏改一处)。

不用页面生命周期兜(`onPageShow` 之类):那会在"用户手动返回列表"时反复触发跳转,
而这里要的是"事件发生的那一刻"。

## 验证

真机(模拟器,装新包后实测):
- 热启 ⇒ `render current custom node: MailDetailDestination` ✓(修之前 0 次)
- 冷启回归 ⇒ 仍然 1 次 ✓(没被这次改动破坏)
- 截图硬证:详情页(返回箭头 + 详情窗格);"加载失败"是我塞的假 mail_id
  (`WARM456`)的**正确**后果 —— 说明确实带着那个 id 去取了

判据:`harmony-push.test.mjs` 18 → 19 条,新增「接线④:热启要能跳」,
**变异验证过两个方向**(deliverRoute 退回"只写格子" ⇒ 红;删掉监听器注册 ⇒ 红)。
它单独存在的理由:接线③那种"有人读"的检查**会放它过去** ——
`aboutToAppear` 里读 pendingRoute 完全满足③,而热启路径是死的。
This commit is contained in:
2026-09-17 19:08:27 +08:00
parent 423ff9fbb2
commit 549836193d
5 changed files with 139 additions and 22 deletions

View File

@ -80,10 +80,12 @@ const SUITE = [
['test/packaging.test.mjs', [], 5],
['test/align-refs.test.mjs', [], 3],
['test/harmony-deviceprobe.test.mjs', ['--experimental-strip-types', '--no-warnings'], 8],
// 契约/形状 15 条 + ★接线 3 条(2026-09-17 收尾:登录后补报 / 换账号补报 / pendingRoute 消费端)。
// 前 15 条钉的是"点"(逻辑对不对),后 3 条钉的是"边"(谁调用、谁消费)——
// 而"写好了但没人调用/没人读"编译一样通过(ArkTS 只编译可达模块,反向对照已复现过)。
['test/harmony-push.test.mjs', ['--experimental-strip-types', '--no-warnings'], 18],
// 契约/形状 15 条 + ★接线 4 条(2026-09-17 收尾:登录后补报 / 换账号补报 /
// pendingRoute 消费端 / **热启**也要能跳)。前 15 条钉的是"点"(逻辑对不对),
// 后 4 条钉的是"边"(谁调用、谁消费)—— "写好了但没人调用/没人读"编译一样通过
// (ArkTS 只编译可达模块,反向对照已复现过)。接线④是真机实测逼出来的:
// 只写 pendingRoute 的版本冷启能跳、热启一次都不跳。
['test/harmony-push.test.mjs', ['--experimental-strip-types', '--no-warnings'], 19],
// 服务器地址(apiBase):补 /api/v1 / 去尾斜杠不吃协议 // / 校验自带修法 /
// 明文只对公网告警 / 404 说清“少了 /api/v1” / 网络错误码分类 / 归一化只有一份实现。
// 值判据跑真逻辑(model/ApiBase.ts);`.ets` 那几条是**静态**接线判据(无设备)。