Flutter 动态化 SDK 接入指引
一、隐私安全说明
Flutter 动态化 SDK
版本:0.0.6
更新时间:2024年11月15日
SDK介绍:为Flutter开发框架提供动态化能力,方便开发者在线更新或修复问题
服务提供方:深圳市腾讯计算机系统有限公司
接入指引:Flutter 动态化 SDK 接入指引
隐私保护规则:《Conch 动态化 SDK 隐私保护规则》
二、获取 SDK 和 License
Flutter动态化属于限制开放功能,有兴趣的用户请联系我们,以获取SDK和相关使用权限。

三、SDK接入
3.1 配置 Flutter SDK
配置 Conch 定制的 FlutterSDK 的环境变量
export PATH=/Users/{YourPath}/conch-flutter-sdk/bin/:$PATH
配置环境后,输入 flutter --version
检查 FlutterSDK 是否已更新
ConchFlutter execute: --version
Flutter 3.7.12 • Conch 1.3.50-new.12 • channel conch/external/3.7.x •
https://git.woa.com/flutter_components/FlutterDynamic/conch-flutter.git
Framework • revision 0ee2bd6fb6 (3 天前) • 2024-09-20 12:44:58 +0800
Engine • revision e219b6e3d7
Tools • Dart 2.19.6 • DevTools 2.20.0
3.2 配置 Conch 参数
在 pubspec.yaml
中添加 conch 插件配置
conch:
enable: true # 是否开启Conch
versionCode: 1.0.1 # 本次构建的产物版本
targetBaseVersions: 1.0.0 # 本次构建补丁的目标产物版本
conchMode: all&hotfix # Conch生效模式,all(类级别热更),hotfix(函数级别热更)、all&hotfix(自由控制函数或类的热更)
licensePath: ./conch_license # 授权证书文件路径
3.3. 接入ConchAPI
3.3.1 通过pub接入
直接在 pubspec.yaml
中添加 conch_api 组件依赖即可
# Conch加载器API依赖
conch_api: ^0.0.6
3.3.2 初始化加载器
App 启动时,尽可能早的初始化 Conch(必须在加载补丁前初始化)
String appId = Platform.isAndroid ? "6e2d1f70bd" : "019c4398e4";
String appKey = Platform.isAndroid ? "1e931146-4905-4654-9ee5-63f450de74d1" : "e57ae316-38ee-47fe-9d21-827115e39e76";
ConchParams params = ConchParams(
appId: appId, // Appid,在发布平台获取
appKey: appKey, // Appkey,在发布平台获取
moduleName: "conch_module", // 模块名称,在发布平台创建
deviceId: "12345", // 设备ID,用于体验阶段控制生效白名单
appVersion: "1.0.0", // 应用版本,用于补丁下发控制生效范围
remoteFirst: true, // 优先加载远端补丁,每次加载前都优先检查并下载远端最新补丁
debugEnable: true,
);
ConchLoaderAPI.init(params);
3.4 预埋补丁切入点
任何类型的补丁需要生效,都需要有一个时机,将执行的代码逻辑切换到补丁中,我们将该时机称为切入点。
这种切换目前无法自动完成,需要开发者在接入时进行预埋,根据不同的目的,需要预埋的方式也有所差异。
3.4.1 整包热更新(暂未提供)
如果我们需要将整个Flutter动态化,即我们要从Flutter的 mian
函数进行切入,将后续的执行逻辑切换到补丁中。
因此我们需要对 mian
函数进行如下改造:
暂不提供
3.4.2. 页面热更新(all 模式支持)
如果我们需要将部分 Flutter 页面动态化,即我们需要从创建这些页面的 Widget 处进行切入,将创建 Widget 的行为切换到补丁中。
因此我们需要对创建 Widget 的地方,或是页面路由管理进行改造,通过 load
接口进行 Widget 创建:
// 通过load接口进行Widget的创建(该接口还提供更多可选参数,可自行查看)
ConchLoaderAPI.load(pageName, (_) => defaultWidgetBuilder());
同时我们需要创建一个页面映射关系的 Map,并使用 @ConfigGenerate()
注解进行标记;
该注解会帮助我们生成这些页面的入口信息,在后续补丁制作时一起打包进入补丁包。
PS: 此处的页面名称即为 load 接口使用的 pageName
// 页面配置信息
()
final Map<String, Function> routes = {
"image": ImagePage.new,
"list": ListPage.new,
"anim": AnimationPage.new,
"touch": TouchPage.new,
"loop": LoopPage.new,
};
3.4.3 函数热更新(hotfix 模式支持)
如果我们只是集成函数级的热更新,那我们并不需要进行特殊的改造,但是我们需要在合适的时机触发补丁加载。
PS: 在补丁加载后函数修改才会生效
// 通过获取加载结果的接口触发补丁预加载
ConchLoaderAPI.getPatchLoadResult(preload: true)
四、补丁制作
4.1 编译基准包
在完成以上接入工作后,我们正常编译一个Flutter的Release产物,该版本即为基准包。
本次构建除了生成可以用于发布的应用产物外,同时也会在 .dart_tool/conch_build
下生成 conch_base_1.0.0.json
的符号文件,
该文件在编译该基准包的补丁时需要用到,因此业务需要归档保存。
PS:
- 符号文件使用的版本号为前面Conch配置中的versionCode
- 补丁制作只能在Release版本上进行,Debug包不支持
4.2 编译补丁包
4.2.1 配置目标版本
首先,我们需要将补丁的目标版本符号文件放到 conch_base
目录下,并将Conch配置中的 targetBaseVersions
字段设置为目标版本。
例如:我们将对 1.0.0 版本构建一个补丁,该补丁版本为 1.0.1,那我们将进行如下配置,同时将 conch_base_1.0.0.json
这个符号文件放到 conch_base
目录下。
conch:
enable: true
versionCode: 1.0.1
targetBaseVersions: 1.0.0
conchMode: all&hotfix
licensePath: ./conch_license
4.2.2 标记补丁范围
Conch提供了多种粒度的补丁制作能力,同时也定义了相关的注解,用于标记补丁范围,简化业务使用成本。
注解: @PatchScope
、@PatchOnly
PS: 注解上可以添加可选的id属性,相同id的注解会被打包到同一个补丁包中
1. 整包热更补丁
使用 @PatchScope
标记 main
函数

释义: @PatchScope
将标记位置的所在 package:xxx
包都打入补丁,一般用于项目的整包热更或某个三方库的整体更新。
PS: 请谨慎使用,由于热更执行必须有切入点,范围过大易造成补丁不必要的浪费,增加加载耗时。
2. 页面热更补丁
使用 @PatchOnly
标记页面类

释义: @PatchOnly
将该类及使用到的类文件打入补丁,并不断扩散到整个业务范围,可保证热更后该页面使用的业务代码是最新的。
3. 函数热更补丁
使用 @PatchOnly
标记函数

释义: @PatchOnly
将标记函数单个打入补丁,不扩散,加载补丁后即可生效。这种用法可最小程度修复bug,非常轻量。
4.2.3 生成补丁产物
将修改后的代码及相关标记和配置准备好后,再次触发Flutter的Release产物构建,则会在 .dart_tool/conch_build/patch_zip/
下生成补丁包。
获取到补丁包后,即可将该补丁包配置到发布平台进行发布,并由SDK自动下载安装,并在合适的时机加载生效。
发布平台的使用可参考《平台使用指引》