Skip to main content

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:

  1. 符号文件使用的版本号为前面Conch配置中的versionCode
  2. 补丁制作只能在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 函数

image

释义: @PatchScope 将标记位置的所在 package:xxx 包都打入补丁,一般用于项目的整包热更或某个三方库的整体更新。

PS: 请谨慎使用,由于热更执行必须有切入点,范围过大易造成补丁不必要的浪费,增加加载耗时。

2. 页面热更补丁

使用 @PatchOnly 标记页面类

image

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

3. 函数热更补丁

使用 @PatchOnly 标记函数

image

释义: @PatchOnly 将标记函数单个打入补丁,不扩散,加载补丁后即可生效。这种用法可最小程度修复bug,非常轻量。

4.2.3 生成补丁产物

将修改后的代码及相关标记和配置准备好后,再次触发Flutter的Release产物构建,则会在 .dart_tool/conch_build/patch_zip/ 下生成补丁包。

获取到补丁包后,即可将该补丁包配置到发布平台进行发布,并由SDK自动下载安装,并在合适的时机加载生效。

发布平台的使用可参考《平台使用指引》