Appearance
download-service-update-case
1. 实验目标与工程要点
这个 Flutter host 样板把 download_service.dart 相关案例落成一条最小可运行状态机:
- 拉远端 metadata
- 下载到 staging /
.part - 校验 size / hash / manifest
- 原子切换 active 版本
- 失败时保留旧版本继续服务
它解决的核心问题是:让页面层明确知道“卡在下载、校验还是晋升”,而不是只收到一个模糊的 success / fail。
2. 深入原理与生活浅显比喻
2.1 生活浅显比喻
可以把它理解成仓库换货架:
activeVersion是当前门店正在卖的货staging是后台正在验收的新货promoting是夜间换货架- 失败时,门店继续卖旧货,不因为新货出问题而停业
2.2 底层原理分析
这个样板把最关键的 UI 语义拆清了:
downloading:字节还在落盘verifying:已经下完,但还不能宣称可用promoting:校验通过后才有资格切 active 指针failed:任何一步失败都应该退回旧版本继续服务
2.3 方案对比矩阵
| 方案 | 通俗比喻 | 底层原理 | 保证特性 | 吞吐性能 | 运行开销 | 适用场景 |
|---|---|---|---|---|---|---|
| 单函数下载成功即完成 | 货车到门口就算上架 | 无阶段拆分 | 最弱 | 高 | 低 | Demo |
| 分阶段状态机 | 收货、验货、上架分开 | metadata + download + verify + promote | 可观察、可恢复 | 中 | 中 | 离线包 / 资源包更新 |
| 直接覆盖 active | 边营业边换货架 | 无 staging 隔离 | 脆弱 | 中 | 低 | 不推荐 |
3. Android / 移动端实战场景与误配事故
3.1 实战场景
- Flutter WebView 离线资源更新
- 模型包 / 配置包升级
- 大文件弱网下载后切换资源版本
3.2 常见误配与事故注意事项
- 下载 100% 就显示“更新成功”,但其实还没做 manifest 校验
- hash 失败后仍误切 activeVersion
- promote 失败后忘记告诉 UI 仍在使用旧版本
3.3 排障思路
先确认失败发生在:
- metadata 获取
- download 落盘
- verify 校验
- promote 晋升
4. 实验源码与运行验证
关键源码
关键参数 / 开关
hash 校验通过:关闭后会停在failed原子切换成功:关闭后会模拟 promotionFailure,保留旧版本
运行方式
bash
cd labs/flutter/host
flutter pub get
flutter run启动后在首页进入 download_service 更新闭环。
预期控制台运行输出
text
[fetchingMetadata] 拉取远端元信息: version=v42, sha256=ok
[downloading] staging/bundle_v42.zip.part 100%
[verifying] 校验 size / sha256 / manifest
[promoting] 准备把 staging_v42 原子切换为 active
[completed] current_version -> v42,旧版本进入 backup