Live View Kit + Push Kit:实况窗远程更新与生命周期接力【鸿蒙心迹】
App 进程都被杀了,外卖进度为什么还能继续更新?

做外卖进度实时展示的时候,最开始的思路很简单:App 里开个轮询,每隔几秒请求一次进度接口,然后更新实况窗。
跑了一段时间发现问题:用户把 App 杀了,轮询停了,实况窗就不动了。用户看着进度条卡在那里,还以为外卖不送了。
这时候才意识到:本地更新依赖 App 进程,进程死了就停了。要让实况窗在 App 不存活的时候还能更新,得把更新链路转移到服务端,用 Push 来推。
一、本地更新和远程更新有什么区别
先把概念理清楚:
| 类型 | 更新方式 | App 存活时 | App 被杀后 |
|---|---|---|---|
| 本地更新 | App 进程轮询 | 正常更新 | 停了 |
| 远程更新 | 服务端 Push | 正常更新 | 继续更新 |
本地更新就是 App 自己在跑,进程活着就能更新。远程更新是服务端通过 Push Kit 把新状态推给系统,系统直接更新实况窗,不需要 App 进程活着。
二、实况窗的三个阶段
一个完整的实况窗生命周期,分三个阶段:
| 阶段 | 操作 | 谁来做 |
|---|---|---|
| 创建 | 创建 LiveView,生成 ID | App 做 |
| 更新 | 更新进度状态 | 本地 or 远程 |
| 结束 | 停止 LiveView | 本地 or 远程 |
创建阶段肯定是 App 做的,因为用户在 App 里下单,点开始配送。更新和结束阶段,可以本地也可以远程。
App 活着的时候,本地更新没问题。App 被杀了,就得靠远程 Push 更新。
这段代码解决什么问题: 创建实况窗。
文件: liveview/LiveViewManager.ets
用途: 创建实况窗
接入位置: 用户下单后
import { liveViewManager } from '@kit.LiveViewKit';
async createDeliveryLiveView(orderId: string) {
const options = {
liveViewType: 'delivery',
title: '外卖配送中'
};
const result = await liveViewManager.createLiveView(options);
const liveViewId = result.liveViewId;
// 把 ID 存到服务端,后面远程更新要用
await this.saveLiveViewIdToServer(orderId, liveViewId);
}
这里最关键的就是:创建完的 LiveView ID,一定要存到服务端。后面服务端要靠这个 ID 来更新对应的实况窗。

三、LiveView ID 和订单 ID 为什么不能混用
很多人搞混了:LiveView ID 是系统生成的实况窗 ID,订单 ID 是业务自己的订单 ID。这两个不是一回事。
服务端要更新实况窗,得用 LiveView ID,不是订单 ID。你把订单 ID 传给服务端,服务端不知道更新哪个实况窗。
正确的做法是:创建的时候把 LiveView ID 和订单 ID 绑定,存到服务端。服务端更新的时候,根据订单 ID 找到对应的 LiveView ID,再用这个 ID 更新。
四、远程更新的完整链路
远程更新的完整链路是这样的:
- 服务端业务状态变化(骑手取餐了);
- 服务端通过 Push Kit 发消息;
- 系统收到 Push,更新实况窗;
- 用户看到进度变了。
整个过程不需要 App 进程活着。系统直接帮你更新了。
API 26 还支持实况窗通过 Push 下载网络图片。比如骑手位置、商品图片,都可以直接推过去。
五、结束阶段为什么要一致
还有个容易踩的坑:结束阶段不一致。
| 情况 | 问题 |
|---|---|
| 服务端订单完成了 | 实况窗还在显示配送中 |
| 用户手动关了实况窗 | 服务端还在继续推 |
正确的做法是:服务端订单完成了,要远程停止实况窗。用户手动关了,也要通知服务端不要再推了。不然就会出现:订单都结束了,实况窗还在转。
六、几个容易踩的坑
第一个坑:LiveView ID 和订单 ID 混用。服务端找不到要更新的实况窗。
第二个坑:只存客户端状态。App 杀了,状态就丢了。
第三个坑:App 被杀后仍依赖本地更新。轮询停了,实况窗不动。
第四个坑:服务端已经结束但实况窗仍存在。订单都完成了,进度条还在转。
第五个坑:更新频率超过限制。推太频繁,系统限流。

这次做实况窗最大的体会是:实况窗不是 App 里的一个组件,是系统级的东西。App 活着的时候本地更新,App 死了就要靠服务端远程推。创建、更新、结束三个阶段的状态一定要一致,不然就会出现各种对不上的情况。
更多推荐




所有评论(0)