腾讯 Kuikly 正式开源,了解一下这个基于 Kotlin 的全平台框架

在 3月的时候通过 《腾讯 TDF 即将开源 Kuikly 跨端框架,Kotlin 支持全平台》 我们大致知道了 Kuikly 的基本情况,Kuikly 是一个面向终端技术栈的跨端开发框架,完全基于kotlin语言开发,提供原生的性能和体验。

按照官方的说法:Kuikly 是基于Kotlin Multiplatform 的 UI 与逻辑全面跨端综合解决方案,由腾讯大前端领域 Oteam(公司级)推出,目的在于提供一套一码多端、极致易用、动态灵活的全平台高性能开发框架

当然,虽然是全平台,但是目前暂时只开源了 Android 和 iOS,鸿蒙部分 5 月才开源,而 Web 和 小程序暂定是 Q2:

官方表示 Kuikly 在腾讯内部本身已经支持全平台小程序(微信/QQ/抖音/支付宝/飞书/百度/360/京东)+ H5 ,个人推测基本是 Kotlin/JS 的能力支持。

那 Kuikly 如何实现跨平台?目前 Kuikly 主要是在 KMP 的基础上实现的自研 DSL 来构建 UI ,比如 iOS 平台的 UI 能力就是 UIkit ,而大家更熟悉的 Compose 支持,目前还处于开发过程中:

SwiftUI 和 Compose 无法直接和 Kuikly 一起使用,但是 Kuikly 可以在 DSL 语法和 UI 组件属性对齐两者的写法,变成一个类 Compose 和 SwiftUI 的 UI 框架,也就是 Compose DSL 大概就是让 Kuikly 更像 Compose ,而不是直接适配 Compose

那么大家可能会有疑问,既然借助了平台控件的能力,那它和 RN 有什么区别?

首先 Kuikly 是直接从编译产物的角度实现跨平台,它的编译产物与原生一致,和 RN 是在运行时转换为原生控件不同,Kotlin 是直接编译为对应平台的原生代码,所以在运行时其实就类似原生 code 。

那 Kuikly 又如何保证多端 UI 一致?答案是 Kuikly 实现了自己的一套「薄原生层」

首先在 Kotlin 层,Kuikly 将虚拟 Dom 方案优化为直调方案,这里 Kotlin View API 直调,避免 JSON 序列化/反序列化损耗,同时只维护一棵树,更轻量和O(1)同步UI更新:

之后,Kuikly 使用"非常薄"的原生层,该原生层只暴露最基本和无逻辑的 UI 组件(原子组件),也就是 Kuikly 在 UI 上只用了最基本的原生层 UI ,真正的 UI 逻辑主要在共享的 Kotlin 代码来实现:

通过将 UI 逻辑抽象到共享的 Kotlin 层,减少平台特定 UI 差异或行为差异的可能性,「薄原生层」充当一致的渲染目标,确保 Kotlin 定义的 UI 元素在所有平台上都以类似的方式显示。

也就是说,Kuikly 虽然会依赖原生平台的控件,但是大部分控件的实现都已经被「提升」到 Kuikly 自己的 Kotlin 共享层,目前 Kuikly 实现了 60% UI 组件的纯 Kotlin 组合封装实现,不需要 Native 提供原子控件

最容易出现不一致的高阶组件都通过 Kotlin 实现,比如 List 列表控件,Kuikly 通过对齐 Native 的 List 内部实现原理,然后再用 Kotlin 重写一次,从而实现真正的高一致性 UI 组件跨平台实现。

所以基于上面的内容,我们再来看 Kuikly UI 官方提供的结构图,是不是就清晰了很多:

  • Core 模块提供了统一的 UI 逻辑实现和 API 接口
  • Render 模块负责在 Android、iOS、HarmonyOS、H5 以及各种小程序等多个平台上实现 UI 的渲染 。

另外在 Kuikly 领域,还有一套名为 KuiklyBase 服务,它是独立于 Kuikly UI 之外,为 Kuikly 提供基础设施支持,比如为 iOS、Android 和鸿蒙三大移动平台提供了统一的底层基建能力:

KuiklyBase 强调在不同平台之间实现高性能的逻辑共享 ,它更像是 KMP 的进一步定制,KuiklyBase 兼容标准的 Kotlin Multiplatform 组件,允许复用成熟的 KMP 组件,比如有些业务各端都已经有 UI 层的实现,仅仅需要非 UI 的业务逻辑实现跨端,而通过 KuiklyBase 的基础设施,也可以满足这种场景的需求。

另外 KuiklyBase 还提供了对 HarmonyOS 平台的全面支持,包括 KN HarmonyOS 编译、调试和构建能力。

也就是 Kuikly 在鸿蒙有支持 Kotlin Native 高性能版本。

同时,KuiklyBase 还提供了强大的多线程和协程能力,支持复杂业务逻辑的跨平台并行处理,以满足高性能场景的需求。

并且在开发工具链方面,KuiklyBase 覆盖了从脚手架搭建到调试、构建、发布和监控的整个流程,特别是支持和 Bugly 和 Shiply 联动提供配套能力。

最后,KuiklyBase 还内置了性能优化工具,并针对 HarmonyOS 和 iOS 提供了优化的调试体验 。

目前使用 KuiklyBase 业务的团队:腾讯视频、浏览器、新闻、输入法、理财通····

当然,这里需要注意的是, KuiklyBase 和 KuiklyUI 一起使用,是存在场景冲突的:

  • KuiklyUI 的 iOS 和鸿蒙动态化方案主要利用了 Kotlin/JS 编译成 js 产物,动态下发到宿主的js引擎去执行
  • KuiklyBase 利用 Kotlin/Native 编译成高性能的二进制产物执行,因此 iOS 和鸿蒙在动态化场景下无法直接兼容

所以,动态化决定了你使用哪个支持:

  • 无动态化诉求场景: KuiklyBase + KuiklyUI = 完美
  • 有动态化诉求场景: KuiklyBase 兼容 js 动态化方案还没完成,短期方案可利用 KuiklyUI 的 Module 方案来作为替代

Kuikly作为一个跨端的 UI 框架, 他本身不具备调用平台 API 的能力, 但是Kuikly提供了一套Module机制,可以通过Module机制将平台的 API 暴露给 Kuikly 侧调用,同时 Kuikly内置了一些通用的 Module , 如果这些 Module 不满足 业务诉求时, 可以通过扩展原生 API 自定义Module, 将更多的宿主平台 API 暴露给 Kuikly 侧使用。

在 KuiklyUI 内部,模块页面分为两种类型:可动态化类型 (内置和动态灵活切换)和纯内置类型(只能内置) :

而可动态化类型部分:

  • 不可直接依赖平台能力
  • 不可使用多线程和协程
  • 不可依赖内置部分
  • 不可依赖使用到了平台能力或多线程协程等能力的 KMP 组件,如果无法避免需要使用相关能力,就需要前面提到额 Kuikly Module 进行解耦调用

核心就是,动态化的只能是 JS 。

最后,以下是 Kuikly 工程的项目结构说明:

ruby 复制代码
.
├── core                    # 跨平台模块,实现各个平台响应式 UI、布局算法、Bridge 通信等核心能力
  ├── src
    ├── commanMain            # 跨平台共享代码、定义跨平台接口 
    ├── androidMain           # Android 平台实现代码 (aar)
    ├── jvmMain               # 泛 JVM 平台代码(不涉及 Android API)(jar)
    ├── iosMain               # iOS 平台实现代码(framework)
├── core-render-android    # android 平台的渲染器模块
├── core-render-ios        # iOS 平台的渲染器模块
├── core-annotations       # 注解模块,定义业务注解 @Page
├── core-ksp               # 注解处理模块,生成 Core 入口文件 
├── buildSrc               # 编译脚本,用于编译、打包、分包产物相关脚本
├── demo                   # DSL 示例代码 
├── androidApp             # Android 宿主壳工程
└── iosApp                 # iOS 宿主壳工程

还有需要注意的是,暂时 Kuikly 的插件还不支持 K2 模式,所以如果你的 IDE 是 K2 模式,需要关闭 K2 才能支持插件:

针对 Mac 用户还提供 kdoctor CI 支持:

可以看到,Kuikly 总得来说还是一个类 RN 框架,但是它又不像 RN 一样的运行时 OEM 原生控件,而是在编译成完成转化为原生代码,并且它抽象出了统一的 「薄原生层」,让大量高阶控件在共享的 Kotlin 层完成实现,只让少量 native 层提供原子组件能力,从而尽可能实现 UI 的多端统一,类似于把原生控件单做 "Canvas" 效果使用。

当然,Kuikly 未来也会兼容 Compose DSL ,但是大概率不会是原本的 Compose ,而是类 Compose 的代码组织方式。

另外,在混合开发领域,在原有 App 集成 Kuikly ,可以把它简单当作如系统 webview 的概念来使用,但是如果在原生列表中嵌入 Kuikly view,目前会因为 Kuikly 本身的异步机制,导致无法同原生列表其它卡片同时生存layout和view结果,造成显示上的不同步。

最后,官方表示 Kuikly 对于 Android 的同学家基本没有学习成本,只要使用过响应式开发的都能上手,而对于 iOS 同学而已,大概就是需要熟悉一下 Kotlin 语法,不过 Kotlin 和 Swift 相近度挺高,所以上手也不会太困难。

目前 Kuikly 已经在 QQ、QQ 音乐、QQ 浏览器、腾讯新闻、搜狗输入法、应用宝、全民K歌、酷狗音乐、酷我音乐、自选股、ima.copilot、微视等多款产品中使用,那么,你觉得你会愿意尝试 Kuikly 吗?

参考链接

相关推荐
小小小小宇2 小时前
手写 zustand
前端
Hamm2 小时前
用装饰器和ElementPlus,我们在NPM发布了这个好用的表格组件包
前端·vue.js·typescript
_一条咸鱼_3 小时前
深度揭秘!Android HorizontalScrollView 使用原理全解析
android·面试·android jetpack
_一条咸鱼_3 小时前
揭秘 Android RippleDrawable:深入解析使用原理
android·面试·android jetpack
_一条咸鱼_3 小时前
深入剖析:Android Snackbar 使用原理的源码级探秘
android·面试·android jetpack
_一条咸鱼_3 小时前
揭秘 Android FloatingActionButton:从入门到源码深度剖析
android·面试·android jetpack
_一条咸鱼_3 小时前
深度剖析 Android SmartRefreshLayout:原理、源码与实战
android·面试·android jetpack
_一条咸鱼_3 小时前
揭秘 Android GestureDetector:深入剖析使用原理
android·面试·android jetpack
_一条咸鱼_3 小时前
深入探秘 Android DrawerLayout:源码级使用原理剖析
android·面试·android jetpack
_一条咸鱼_3 小时前
深度揭秘:Android CardView 使用原理的源码级剖析
android·面试·android jetpack