laoyang
bd3afb7bd1
0.0.8:卡片同步尝试用短时任务延长窗口(10 秒 → 最多 60 秒)
背景:上一步实现了"卡片 30 分钟刷新驱动同步",但受 FormExtensionAbility
"回调后进程仅存续 10 秒"的硬限制,同步可能被回收掐断。
用户建议:能不能调一个后台进程、或让异步同步在 10 秒后继续跑一会儿?
调研结论(已核实官方文档):
1. ❌ ServiceExtensionAbility(独立后台服务)—— 三方应用**根本不能用**:
官方"仅系统应用可使用",需 Full SDK + AllowAppUsePrivilegeExtension 特权 + 设备白名单。
2. ❌ 从卡片进程 startAbility 拉起主应用 —— 会被拦:官方《组件启动规则》
"位于后台的 UIAbility 应用,启动组件需校验 ohos.permission.START_ABILITIES_FROM_BACKGROUND,
**该权限仅系统应用可申请**"。
(卡片 postCardAction 的 `call` 事件确实能"后台拉起 UIAbility 且不弹界面",
但**只能由用户点击卡片触发**,系统定时刷新的 onUpdateForm 用不上。)
3. ✅ **短时任务 `requestSuspendDelay`** —— 可行路径:让进程在后台多活一会儿,
单次最长 3 分钟(低电量 1 分钟),实际时长以 actualDelayTime 为准。
本次改动(BackgroundSyncRunner):
- 新增 `acquireCardWindow()`:尝试申请短时任务,
· **容错尝试**:官方规定应在"应用在前台"或"onBackground 回调"里调用,
卡片进程是否符合**未知** → 抛错 / 时长为 0 时**优雅退回 9 秒软超时**,不阻塞流程;
· 留 **15 秒余量**提前收手(保证能干净地 cancelSuspendDelay,
否则超时不取消会被系统强制终止进程并浪费配额);
· 加 **60 秒/次总上限**(CARD_MAX_TOTAL_MS)。
- 新增 `releaseCardWindow()`:无论成败都在 finally 里释放,归还配额。
- `runOnceThrottledByCard()` 改为按"实际可用窗口"设软超时,并记录窗口秒数到日志。
⚠️ 配额账(关键取舍):
短时任务**单日总配额仅 10 分钟**,且**只在被挂起后计时**(10 秒内跑完不计费)。
· 正常网络下增量同步几秒完成 → 多落在 10 秒窗口内 → 消耗极少;
· 网络慢才会吃配额;吃满 10 分钟后自动降级为 9 秒软超时,不报错;
· ⚠️ **不能吃光配额**:EntryAbility.onBackground 也申请短时任务(兜"退后台那一次同步"),
故卡片侧设 60 秒/次上限 + 15 秒提前释放,避免把它饿死。
验证:编译通过(BUILD SUCCESSFUL);窗口预算逻辑离线用例通过
(申请被拒/时长为0 → 9 秒;低电量 → 45 秒;正常 3 分钟 → 被 60 秒上限截断;40 秒 → 25 秒)。
2026-10-14 16:51:56 +08:00
..
2026-10-14 16:51:56 +08:00
2026-09-13 15:50:37 +08:00
2026-09-13 15:50:37 +08:00
2026-09-13 15:50:37 +08:00
2026-09-13 15:50:37 +08:00