棉宇宙 Flutter 热更新是如何落地的

棉宇宙App采用原生宿主 + Flutter模块(Add-to-App) 架构,并非纯Flutter应用,因此Flutter热更无法仅通过简单集成SDK实现,必须深度联动现有Jenkins整包流水线、Metax出包体系与自研控制面,形成标准化落地链路。本文聚焦项目实际落地流程,不阐述FlutterPatch控制面从零搭建逻辑。

一、核心落地结论

1. 流水线核心:两条核心Jenkins任务

Jenkins Job类型 核心职责 关联能力与参数
整包Job 打包生成APK/IPA安装包,同步完成OTA基线版本登记,为后续热更提供基准版本 依托metax upload能力,绑定版本信息、渠道属性,产出热更基线快照
热更Job 基于已上线的基线版本,生成差分热更补丁,完成补丁校验、发布与放量 依赖PLATFORM、RELEASE版本参数,支持白名单、预检校验、灰度回滚能力

2. 设备侧核心能力

设备端复用Shorebird updater底层能力,自定义对接内部自研控制面(对内命名Meta Code Push),核心规则如下:

  • 补丁生效:Dart代码补丁需冷启动生效,无热重启即时生效能力
  • 资源热更:图片等静态资源不依赖原生Assets加载,需专用热更API适配
  • 链路隔离:设备OTA请求、补丁校验请求均指向内部专属地址,不走官方公共域名

二、技术架构选型原因

项目未采用"简单接入热更SDK"的轻量化方案,是基于早期落地踩坑后的最优决策,核心约束条件有三点:

1. 必须自建热更控制面

官方Shorebird云服务无法适配内网研发环境,存在数据出域风险、国内网络下载不稳定、内网制品无法互通等问题。因此仅复用Shorebird引擎构建能力,设备数据、补丁校验、制品管理全部迁移至内部控制面,彻底隔离官方云服务链路。

2. 统一Metax出包入口

项目所有打包流程(Unity子模块、多渠道包、Appwrite缓存、原生宿主打包)均基于Metax体系。若热更单独搭建命令行流程,会提升研发成本、增加流程出错概率。因此将flutterpatch能力封装至Metax内部,统一开关、环境变量、版本发布、缓存回填的操作入口。

3. 整包与热更规范强对齐

热更补丁必须基于整包Job登记的基线版本生成,严格按照release-version(buildName+buildNumber)版本号对齐。版本不匹配会直接导致补丁下发失败、设备解析异常、功能不生效等问题,因此两套流水线必须遵循同一套版本规范与出包环境。

综上,棉宇宙Flutter热更完整落地链路为:Jenkins → Metax → FlutterPatch → 自研控制面,核心载体是流水线体系,而非单一SDK。

三、工程侧接入规范

1. 双配置文件开关隔离

工程通过两个独立配置文件区分「出包热更开关」和「设备热更链路配置」,禁止混用、新增自定义字段:

(1)metaapp_flutter/pubspec.yaml

仅用于控制打包阶段是否开启FlutterPatch热更能力,不参与设备运行逻辑:

yaml 复制代码
metax:
  shorebird_enabled: true

(2)metaapp_flutter/shorebird.yaml

仅保留控制面认可的标准字段,新增自定义字段会触发CLI报错,配置如下:

yaml 复制代码
app_id: <uuid>
base_url: https://ota.example.com  # 设备OTA、控制面统一请求地址
auto_update: false                 # 按需配置产品自动更新策略
upload_baselines: true
upload_patch_resources: true

2. 热更开关优先级规则

热更启用优先级从高到低依次为:命令行--useFlutterPatch > 环境变量 > pubspec的metax.shorebird_enabled > 默认关闭。禁止通过配置文件是否存在判断热更状态,鸿蒙系统、源码编译场景会强制屏蔽热更链路,与文件无关。

3. 原生宿主适配改造

Android端

引入FlutterPatch专属Maven依赖坐标,开启keepDebugSymbols配置,保留调试符号,为补丁差分计算提供依赖,避免补丁解析失败。

iOS端

嵌入专属引擎xcframework,产物同步时将ShorebirdFlutter.xcframework重命名为宿主识别的Flutter.xcframework,适配CocoaPods宿主依赖规则。

所有原生适配规则均固化在metax init flutterpatch接入清单中,出包前需执行预检命令,避免流水线末端打包失败。

四、业务侧适配

热更接入后最常见的问题是「补丁下发成功,但图片资源不生效」,核心原因是FlutterGen原生.image()方法为实例方法,Dart扩展无法重写覆盖,无法适配热更资源差分逻辑。

1. 错误写法(无法热更)

arduino 复制代码
Assets.images.home.icSearchHome.image(width: 24, height: 24);

2. 正确热更写法

arduino 复制代码
// 写法1:专用热更图片API
Assets.images.home.icSearchHome.patchImage(width: 24, height: 24);
// 写法2:通用热更资源加载API
FlutterPatch.assetImage(Assets.images.home.icSearchHome.path);

代码评审核心卡点:所有静态图片资源必须替换为上述热更专属API,禁止保留原生Assets加载方式。

五、完整流水线落地流程

1. 整包流水线:基线版本登记(热更前置条件)

市场包、测试包沿用原有metax upload打包逻辑,开启shorebird_enabled后自动新增热更基线处理流程:

  1. 自动生成FLUTTERPATCH_RELEASE_VERSION版本号(x.y.z+build),与应用版本强绑定;
  2. 根据包类型自动打环境标签:市场包标记prod、测试包标记test,用于控制台筛选管理;
  3. 执行flutterpatch release命令,编译生成AAR/引擎框架产物,上传至控制面形成基线快照;
  4. 产物缓存至本地并同步至Appwrite,后续宿主版本未变更时可复用产物,避免重复编译。

出包机环境硬性要求

  • 配置全局FLUTTERPATCH_TOKEN,控制面仅校验该令牌权限;
  • 禁止配置SHOREBIRD_HOSTED_URL,打包流程会自动清空该配置,防止链路指向官方云服务;
  • 出包前执行预检命令:metax init flutterpatch,校验CLI、Token、base_url、FVM版本合法性。

核心逻辑:整包Job成功执行,即代表商店包与热更基线同步完成,为后续热更补丁提供有效适配靶版本。

2. 热更流水线:补丁生成与放量

仅针对Dart逻辑、可热更资源变更场景使用,版本基线无变更时无需整包,流水线流程如下:

  1. 参数录入:填写PLATFORM(平台)、RELEASE(基线版本号),可选配置白名单、设备唯一ID;
  2. 合法性预检:执行metax check-ota,生成资源适配报告,输出unsupported/supported/resources三种状态,不支持热更的变更直接中断流程;
  3. 补丁生成:校验通过后执行metax patch,生成对应平台差分补丁;
  4. 灰度放量:默认白名单真机灰度,验证通过后关闭白名单全量发布;
  5. 异常回滚:问题版本直接控制台rollback撤销发布,不使用反向补丁兜底。

核心参数说明

  • CHECK_ONLY=true:仅生成OTA适配检测报告,不产出补丁,用于评审变更是否支持热更;
  • FORCE_PATCH:跳过预检强制生成补丁,高危操作,仅用于线上排障,与CHECK_ONLY互斥;
  • WHITELIST/UNIQUE_IDS:设备灰度管控,规避全量发布风险。

关键约束

iOS热更仅真机有效,模拟器无法验证Shorebird补丁生效状态,所有测试必须基于真机完成。

3. 设备端生效链路

  • Dart代码补丁:设备发起校验 → 差分补丁下载 → 应用冷启动后生效
  • 图片资源补丁:资源合法性校验 → 差分资源拉取 → 业务通过patchImage API加载生效。

补充:桌面客户端支持本地工程预览、线上状态查询、临时补发能力,但正式线上发版以Jenkins流水线为准,值班运维仅需关注流水线参数配置。

六、热更能力边界

1. 支持热更范围

  • Dart业务逻辑代码变更;
  • 图片 音频 视频 基础资源(需要提前代码写好也可以写完走热更)

2. 不支持热更、必须整包场景

  • 原生代码、插件、Flutter引擎大版本变更;
  • 字体文件等特殊资源变更(check-ota可自动拦截);
  • 应用核心用途变更、违规文案修改(审核红线);
  • 无有效整包基线版本,无法匹配差分补丁。

技术定位:本方案基于Shorebird Dart补丁能力+自研控制面实现,区别于Fair动态化方案,热更仅用于线上紧急修复、轻度运营迭代,无法替代应用商店整包发布

相关推荐
恋猫de小郭3 小时前
AndroidX 新增 Security State ,支持可编程的系统安全状态查询
android·前端·flutter
zihan5183 小时前
自己做软件日记9/21 得到了一个良好的文件结构框架
后端·flutter·前端框架·android studio
ZFJ_张福杰1 天前
【Flutter】Flutter 中有哪些耗时操作?从 UI 卡顿到 Isolate 性能优化
flutter·性能优化·卡顿·isolate
sakiko_1 天前
Flutter:Dart学习笔记1:基础UI组件等
flutter
9765033351 天前
iOS 上架 4.3a 被拒【uniapp专讲】
flutter·ios·objective-c·uniapp·swift
传奇开心果编程2 天前
【Flutter入门练中学】第2课:布局系统
学习·flutter·ui
君赏2 天前
FlutterPatch:把 Shorebird 热更新的控制面搬回自己服务器
flutter
用户2181697049302 天前
Flutter tootip 轻量级提示
flutter
用户2181697049302 天前
Flutter 拖拽 Draggable DragTarget
flutter