订单都送到了,实况窗还卡在“骑手接单”
把外卖进度从普通通知迁到实况窗,第一版跑起来挺顺,创建、更新、结束三个接口都通了。上线之后投诉来了:用户锁屏上看实况窗,骑手已经点了送达,窗上还写着“正在配送”。日志里 updateLiveView 明明在调,返回码有时候是成功有时候是失败。问题不在你的业务逻辑,在实况窗的更新通道有独立的频控和生命周期规则,拿普通通知的思维往里套,高频更新会被限流,进程被杀之后窗也不会自动消失。

本地更新有硬上限,高频轮询不是正确姿势
本地创建和更新在系统级有明确配额:创建最多 15 次/秒、更新最多 30 次/秒,单应用维度更低,创建 10 次/秒、更新 20 次/秒,超限直接丢弃,不排队、不重试。如果你的业务每两秒上报一次骑手位置,然后原样转发给 updateLiveView,很快就会撞上限流。正确做法是端侧做去抖和合并,只保留最新状态,不要逐条转发。秒级计时这类纯展示效果交给计时器样式,不要用更新接口去“刷秒数”。
typescript
import { liveViewManager } from '@kit.LiveViewKit';
let seq: number = 0;
async function updateRiderStatus(
liveViewId: number,
statusText: string
): Promise<void> {
seq += 1; // sequence 必须单调递增,不是每次重置
const liveView: liveViewManager.LiveView = {
id: liveViewId,
event: 'DELIVERY',
sequence: seq,
liveViewData: {
primary: { title: '配送中', content: [{ text: statusText }] },
},
};
try {
await liveViewManager.updateLiveView(liveView);
} catch (e) {
// 频控或状态冲突时,记录并等待下一次业务节点更新
console.warn(`liveview update skipped: ${JSON.stringify(e)}`);
}
}
sequence 是实况窗判断“哪个状态更新”的依据,每次更新递增,不能回退、不能重置。如果两条更新乱序到达,sequence 更大的那条胜出。catch 里不要立即重试,限流状态下重试只会继续撞墙,等下一个业务节点再更新才是对的。
杀进程后窗还挂着,是生命周期模式没选对
实况窗默认不随应用进程结束而自动关闭。用户从最近任务里划掉应用,锁屏上的实况窗还在,点进去是个死的。API 26 及以上可以在创建时设置 lifeCycleMode = AUTO_STOP_WHEN_APP_TERMINATE,让实况窗跟随应用进程结束而消失。如果你的业务生命周期完全由端侧管理、没有服务端 Push 兜底,这个模式必须打开。正常结束用 stopLiveView,不要用 notificationManager.cancel 去关,否则后续同一个 ID 的更新和结束会受到限制。

权益没开通,测试环境能跑、Release 包报错
实况窗依赖 AGC 侧 Live View Kit 权益,未开通时调用 startLiveView 报 67108900,上架后功能失效。开发阶段可以申请设备白名单调试,但白名单不是权益本身,Release 包必须等权益正式开通。排查顺序是:先看 startLiveView 的返回码,1003500005 指向权益,1003500008 指向频控,各自对应不同的处理路径,不要混在一起调。
更多推荐

所有评论(0)