Skip to main content

Kuikly 动态化 SDK 接入指引

一、隐私安全说明

Kuikly 动态化 SDK

版本:2.0.0-beta1

更新时间:2025年08月05日

SDK介绍:为 Kuikly 开发框架提供动态化能力,方便开发者在线更新或修复问题

服务提供方:深圳市腾讯计算机系统有限公司

接入指引:Kuikly 动态化 SDK 接入指引

隐私保护规则:《Shiply 容器动态化 SDK 隐私保护规则》

二、获取 SDK 和 License

Kuikly 动态化属于限制开放功能,有兴趣的用户请联系我们,以获取 SDK 和相关使用权限。

咨询二维码

三、运行时 SDK 接入

PS:在正式接入 Kuikly 动态化之前,请确保自己的项目已按照 Kuikly 开源版本的要求进行了接入和改造。

动态化版本相较于开源版本,在接入上的主要差异:

  1. SDK 发布源需要修改,以获得支持动态化的制品
  2. 平台侧少量接口参数有变化,以支持动态产物的查找和加载
  3. 跨端侧的模块配置需要修改,以支持 JS 产物的构建
  4. 同时需要引入新的动态化构建插件,以生成动态发布产物

3.1 Android 端接入及改造

1. 更换依赖的组件

修改项目的build.gradle.kts配置,添加新的 Maven 仓库和 Gradle 插件依赖

buildscript {
repositories {
// Kuikly Dynamic Repo
maven {
url = uri("https://maven.cnb.cool/tencent-tds/kuikly-dynamic/-/packages/")
credentials {
username = "分配的用户名"
password = "分配的Token"
}
}
}

dependencies {
classpath("com.tencent.kuikly:dynamic-gradle-plugin:2.0.0-beta1-2.0.21")
}
}

allprojects {
repositories {
// Shiply Repo
maven { url = uri("https://maven.cnb.cool/tencent-tds/shiply-public/-/packages/") }
// Kuikly Dynamic Repo
maven {
url = uri("https://maven.cnb.cool/tencent-tds/kuikly-dynamic/-/packages/")
credentials {
username = "分配的用户名"
password = "分配的Token"
}
}
}
}

将开源的组件依赖更换为支持动态化的组件

dependencies {
implementation("com.tencent.kuikly:core:2.0.0-beta1-2.0.21")
implementation("com.tencent.kuikly:core-render-android:core:2.0.0-beta1-2.0.21")
}

2. 修改加载框架接入代码

为了支持动态化,我们修改了加载框架代码,并扩展了onAttach接口,在接口中增加了新的参数moduleName

模块作为动态产物下发的管理单位,一个模块可以有一个或多个页面组成,在打开页面时需要传入。

开发者可以根据自己项目的接入情况,适当修正自己的代码,以解决相关的编译告警。

以下是修改后的接口描述:

open class KuiklyRenderViewBaseDelegator {
/**
* 初始化KuiklyView
* @param moduleName 模块名字
* @param pageName 页面名字
* @param pageData 页面数据
* @param size 根View大小, 非必传
*/
fun onAttach(
moduleName: String,
pageName: String,
pageData: Map<String, Any>,
size: Size? = null
)
}

interface IKuiklyView {
/**
* 初始化KuiklyView
* @param moduleName 模块名字
* @param pageName 页面名字
* @param pageData 页面数据
* @param size 根View大小, 非必传
*/
fun onAttach(
moduleName: String,
pageName: String,
pageData: Map<String, Any>,
size: Size? = null
)
}

3. 接入并使用动态产物更新框架

KuiklyDynamic用于云端动态产物的检查、下载、更新管理。 在 App 启动后的合适时机(一般是在隐私合规弹窗通过后),可以初始化该模块。

初始化KuiklyDynamic

// 构造业务参数
val params = KuiklyDynamicParams(
this,
"c82963a5a2", // appId
"3c0286e3-12f1-4609-b620-ecd37d41d00f", // appKey
"123456", // 用户ID
"1.0.0", // 应用版本
"OPPO", // 厂商
"Y1031", // 机型
)
// 初始化Kuikly动态化组件
KuiklyDynamic.init(params)

通过checkUpdate()检查模块是否有更新:

KuiklyDynamic.checkUpdate("moduleName", object : ICheckUpdateCallback {
override fun onComplete(success: Boolean, installResult: InstallResult) {
// TODO:
}
})

PS: 开发者可以根据自己的需要,在合适的时机触发模块的更新检查。新的产物会自动下载到本地,并在下次打开页面时生效。

3.2 iOS 端接入及改造

1. 更换依赖的组件

iOS 端需要将 Kuikly 开源组件 OpenKuiklyIOSRender 替换成 KuiklyDynamic

具体步骤是:

  • 删除 Podfile 中的 OpenKuiklyIOSRender

  • 在 Podfile 中引入 KuiklyDynamic.xcframework

  • 在 Podfile 中引入 dynamic_core.xcframework

系统要求:

  • iOS版本:iOS 14.1 及以上
  • Xcode版本:Xcode 12.0 及以上
  • 开发语言:Objective-C / Swift
  • 架构支持:真机(arm64)、模拟器(arm64、x86_64)

当前推荐版本:

  • KuiklyDynamic:2.0.0-beta1
  • dynamic_core:2.0.0-beta1-2.0.21-SNAPSHOT

完整接入文档: iOS-KuiklyDynamic-Integration-Guide.md

iOS Demo: Demo 仓库

CocoaPods 集成(推荐)

在你的 Podfile 中添加以下依赖:

# iOS 最低版本要求
platform :ios, '14.1'

target 'YourApp' do
# KuiklyDynamic 主要SDK
pod 'KuiklyDynamic', :git => 'https://cnb.cool/tencent-tds/KuiklyDynamic.git', :tag => '2.0.0-beta1'

# dynamic_core 核心模块
pod 'dynamic_core', :git => 'https://cnb.cool/tencent-tds/KuiklyDynamic.git', :tag => '2.0.0-beta1'

end

2. 修改加载框架接入代码

为了支持动态化,我们修改了加载框架代码。模块作为动态产物下发的管理单位,一个模块可以有一个或多个页面组成,在打开页面时需要传入。

开发者可以根据自己项目的接入情况,适当修正自己的代码,以解决相关的编译告警。

  1. KRRouterProtocol协议新增moduleName参数
@protocol KRRouterProtocol <NSObject>

@required
/*
* @brief 打开kuikly页面
* @param moduleName 动态产物模块名
* @param pageName kuikly页面名,为@Page注解名
* @param pageData 页面的传参,数据类型为jsonObject,key&value为字符串/Number等基础数据类型
* @param controller 当前页面所在controller
*/
- (void)openPageWithModuleName:(NSString *)moduleName // 新增 moduleName 参数
pageName:(NSString *)pageName
pageData:(NSDictionary * _Nullable)pageData
controller:(UIViewController *)controller;
/*
* @brief 关闭当前页
* @param controller 需要关闭的controller
*/
- (void)closePage:(UIViewController *)controller;

@end
  1. KuiklyRenderViewControllerDelegator协议增加moduleName参数。
/*
* @brief 创建实例对应的初始化方法(支持动态产物模块名).
* @param moduleName 动态产物模块名,用于检查是否存在对应的动态产物
* @param pageName 页面名 (对应的值为kotlin侧页面注解 @Page("xxxx")中的xxx名)
* @param pageData 页面对应的参数(kotlin侧可通过pageData.params获取)
* @param frameworkName kuikly kmm工程打包的framework名字,如shared.framework,则传入 @"shared"(注:也可以通过fetchContextCode接口传入)
* @param hotReloadIp 热重载模式下的本地代理电脑ip地址,如果为模拟器,该ip则为空字符串(注:若不开启热重载,该参则传入nil值)
* @return 返回KuiklyRenderViewControllerDelegator实例
*/
- (instancetype)initWithModuleName:(NSString * _Nullable)moduleName
pageName:(NSString *)pageName
pageData:(NSDictionary *)pageData
frameworkName:(NSString * _Nullable)frameworkName
hotReloadIp:(NSString * _Nullable)ip;

- (instancetype)initWithModuleName:(NSString * _Nullable)moduleName
pageName:(NSString *)pageName
pageData:(NSDictionary *)pageData
frameworkName:(NSString * _Nullable)frameworkName;

- (instancetype)initWithModuleName:(NSString * _Nullable)moduleName
pageName:(NSString *)pageName
pageData:(NSDictionary *)pageData;

3. 接入并使用动态产物更新框架

KuiklyDynamic用于云端动态产物的检查、下载、更新管理。 在 App 启动后的合适时机(一般是在隐私合规弹窗通过后),可以初始化该模块。

初始化KuiklyDynamic

// 在 AppDelegate 或合适的时机初始化
- (void)viewDidLoad {
[super viewDidLoad];

// 创建初始化参数
KuiklyDynamicParams *params = [[KuiklyDynamicParams alloc]
initWithContext:self // 上下文对象
appId:@"c82963a5a2" // 应用ID
appKey:@"3c0286e3-12f1-4609-b620-ecd37d41d00f" // 应用密钥
userId:@"123456" // 用户唯一标识
appVersion:@"1.0.0" // 应用版本
manufacturer:@"Apple" // 设备制造商
model:@"iPhone" // 设备型号
env:@"online" // 环境标识
customParams:@{}]; // 自定义参数

// 初始化 KuiklyDynamic
[[KuiklyDynamic shared] initializeWithParams:params];
}

检查模块更新:

// 实现更新检查代理
@interface YourViewController : UIViewController <KuiklyDynamicCheckUpdateDelegate>
@end

@implementation YourViewController

- (void)checkForUpdates {
// 检查指定模块的更新
[[KuiklyDynamic shared] checkUpdateForModule:@"your_module_name"
delegate:self];
}

// 更新完成回调
- (void)onCheckUpdateComplete:(BOOL)success
installResult:(KuiklyDynamicInstallResult *)installResult {
if (success && installResult.isSuccess) {
NSLog(@"模块更新成功:%@", installResult.moduleName);
NSLog(@"版本:%lld", installResult.version);
NSLog(@"结果:%@", installResult.resultName);
} else {
NSLog(@"模块更新失败:%@", installResult.resultName);
}
}

@end

PS: 开发者可以根据自己的需要,在合适的时机触发模块的更新检查。新的产物会自动下载到本地,并在下次打开页面时生效。

3.3 跨端层接入及改造

1. 修改 KMP 配置

kotlin {
// 1. 添加生成 js 目标产物
js(IR) {
moduleName = "nativevue2"
browser {
webpackTask {
outputFileName = "${moduleName}.js"
}
commonWebpackConfig {
output?.library = null
}
}
binaries.executable()
}

// 2. 将开源的组件依赖更换为支持动态化的组件
val commonMain by sourceSets.getting {
dependencies {
implementation("com.tencent.kuikly:core:2.0.0-beta1-2.0.21")
api("com.tencent.kuikly:core-annotations:2.0.0-beta1-2.0.21")
}
}

// 3. 添加 js 目标产物的依赖
val jsMain by sourceSets.getting {
dependsOn(commonMain)
}
}

2. 修改 KSP 配置

dependencies {
// 1. 将开源的组件依赖更换为支持动态化的组件
compileOnly("com.tencent.kuikly:core-ksp:2.0.0-beta1-2.0.21") {
// 2. 添加 js 目标产物的支持
add("kspJs", this)
}
}

3. 引入动态化构建插件

plugins {
// 1. 添加 Kuikly 动态化插件
id("kuikly")
}

// 2. 配置 Kuikly 动态化插件
kuikly {
js {
outputName("nativevue2")
// 需要构建的动态化页面,每次构建按照实际需求填写
addSplitPages(listOf("image_demo", "mask_demo", "example"))
}
dynamicApk {
shellProjectName = "apk-builder"
// 需要构建的动态化页面,每次构建按照实际需求填写
addSplitPages(listOf("image_demo", "mask_demo", "example"))
}
shiply {
// 平台颁发的 License
license = project.file("kuikly_license").absolutePath
}
}

动态化构建插件支持两种类型的动态产物,apk 产物提供给 Android 平台使用,js 产物提供给 iOS 平台使用。

Android 平台的动态产物构建,需要依赖一个壳儿工程,开发者需要自行在项目中创建,并将该壳儿工程的名字填写到shellProjectName 字段。

PS:该壳儿工程建议直接使用 KuiklyDynamicDemoapk-builder模块, 并修改apk-builder模块中的跨端层模块依赖,修改为业务实际的跨端层模块。

dependencies {
implementation(project(":demo"))
}

四、动态产物构建

按照以上流程完成 Kuikly 动态化 SDK 的接入及项目改造后,项目应该跟接入前一样,能正常的构建启动,并加载内置页面。

同时,我们的跨端模块下会新增加一系列 Gradle Task,用于触发页面的动态产物构建和打包行为,如下图所示:

Kuikly Dynamic Gradle Tasks

4.1 构建 Android 平台动态产物

修改dynamicApk下的addSplitPages字段,将本次构建的模块所涉及的动态页面填入其中。

kuikly {
dynamicApk {
// 需要构建的动态化页面,每次构建按照实际需求填写
addSplitPages(listOf("image_demo", "mask_demo", "example"))
}
}

执行./gradlew packSplitApkRelease,触发动态化产物的构建。

构建成功后, 可在跨端模块的build/outputs/kuikly/apk/release/split/final/kuikly_dynamic.zip处找到构建产物, 该产物作为最终的发布产物,需要上传到发布平台后,经由网络下发到客户端,才可被动态加载。

4.2 构建 iOS 平台动态产物

修改js下的addSplitPages字段,将本次构建的模块所涉及的动态页面填入其中。

kuikly {
js {
// 需要构建的动态化页面,每次构建按照实际需求填写
addSplitPages(listOf("image_demo", "mask_demo", "example"))
}
}

执行./gradlew packSplitJSBundleRelease,触发动态化产物的构建。

构建成功后, 可在跨端模块的build/outputs/kuikly/js/release/split/nativevue2.zip处找到构建产物, 该产物作为最终的发布产物,需要上传到发布平台后,经由网络下发到客户端,才可被动态加载。

4.2 动态产物下发

生成的动态产物需要上传到发布平台后,经由网络下发到客户端,才可被动态加载。

如何在发布平台进行动态产物下发,请查看:发布平台使用指引

五、测试体验 Demo

对于想快速体验的开发者,也可以直接使用我们的测试 Demo 进行体验。 在正式接入时,该 Demo 也是一个很好的参考样例,可以提升开发者的接入速度。

Demo 地址:KuiklyDynamicDemo