kotlin multiplatform 和 Flutter 和 React Native相比起来有什么优势, 有了Flutter为何官方又推出kotlin multiplatform呢
我们来详细拆解一下 Kotlin Multiplatform(KMP)、Flutter 和 React Native(RN)的优劣势,并重点分析为什么在有了 Flutter 之后,JetBrains/Google 还会推出 KMP。
首先,用一个表格来直观对比三者的核心差异:
特性 | Kotlin Multiplatform (KMP) | Flutter | React Native (RN) |
---|---|---|---|
核心技术 | 共享业务逻辑,UI 使用原生或跨平台框架(如 Compose Multiplatform) | 自绘引擎(Skia),完全一致的 UI 和逻辑 | JavaScript 桥接,使用原生组件 |
编程语言 | Kotlin | Dart | JavaScript/TypeScript |
UI 实现方式 | 选项1 :各平台原生 UI(UIKit/Swift, Jetpack Compose) 选项2:Compose Multiplatform(共享 UI) | 使用 Flutter 引擎自绘,外观和行为完全一致 | 使用 JavaScript 描述 UI,映射为原生组件,外观随系统 |
性能 | 逻辑层: 接近原生(编译为原生代码) UI层(原生方案): 与原生应用一致 | 高且稳定。自绘引擎避免了桥接开销,性能体验一致,但启动体积较大 | 依赖 JavaScript 桥接。早期性能瓶颈明显,但新架构(Fabric/TurboModules)大幅改善 |
开发生态 | 可与现有 Android 库无缝集成;iOS 需 KMP 包装。强依赖于 Kotlin 生态。 | 生态完善且独立,拥有丰富的 pub.dev 包,但无法直接使用原生库。 | 生态极其丰富(npm),有大量社区封装的原生模块。 |
学习曲线 | 需熟悉 Kotlin 和平台特性(如果做原生 UI)。对 Android 开发者非常友好。 | 需学习 Dart 和全新的声明式 UI 范式(Widget)。对任何背景的开发者都是新的。 | 对 Web 开发者极其友好。需理解 React 理念和原生桥接概念。 |
Kotlin Multiplatform (KMP) 的核心优势
KMP 的核心理念是 "共享业务逻辑,灵活处理 UI"。这与 Flutter/RN 的"一次编写,处处运行"有本质区别。
-
极致的原生体验和性能(尤其是在 UI 层)
- 如果你选择让 iOS 使用原生 SwiftUI/UIKit,Android 使用 Jetpack Compose,那么你的应用在各自平台上的外观、感觉和性能都将与纯原生应用毫无二致。这是 Flutter(自绘)和 RN(组件映射延迟)难以绝对保证的。
- 业务逻辑被编译为平台原生代码(在 Android 上是字节码,在 iOS 上是 Swift 兼容的二进制),没有解释器或桥接的性能损耗,逻辑执行效率极高。
-
无缝接入现有原生项目(增量式集成)
- 这是 KMP 的杀手级应用场景。你可以在一个庞大的现有原生 Android 或 iOS 应用中,逐步地将一些共享的业务逻辑(如数据验证、网络请求、数据缓存等)用 KMP 抽离和替换,而无需重写整个应用的 UI。这对于大型团队和成熟产品来说,风险极低,迁移路径平滑。
-
更小的包体积增量(仅共享逻辑时)
- 如果只共享业务逻辑,KMP 带来的包体积增加非常小,因为它主要是添加了编译后的 Kotlin 代码和必要的运行时库。相比之下,Flutter 需要嵌入整个 Dart 运行时和渲染引擎,初始体积较大。
-
强大的平台特定 API 调用能力
- 在 KMP 中,使用
expect
/actual
机制来定义和实现平台相关代码非常直观和类型安全。你可以轻松地为特定平台(如 Android 或 iOS)编写优化代码,然后在共享代码中调用统一的接口。这种"平台特异性"是一等公民。
- 在 KMP 中,使用
-
对 Android 开发者生态的天然亲和力
- Kotlin 已经是 Android 开发的官方首选语言。对于 Android 团队来说,采用 KMP 几乎没有语言上的学习成本,可以快速上手并利用现有的知识和库。
有了 Flutter,为何官方又推出 KMP?
这个问题需要从两个"官方"的角度来理解:Google 和 JetBrains。
-
哲学和定位的根本不同
- Flutter 的定位 :提供一个完整的应用开发框架 ,包括渲染引擎、UI 组件和工具链。它的目标是让开发者能够用一套代码库快速构建一个在多个平台上体验高度一致 的应用程序。它追求的是 "一致性" 和 "开发效率"。
- KMP 的定位 :它本质上是一个 "代码共享工具" ,而不是一个完整的 UI 框架。它的目标是解决业务逻辑的重复编写问题,同时最大限度地尊重和利用原生平台的能力和体验 。它追求的是 "原生体验" 和 "渐进式集成"。
你可以把 Flutter 看作是一家提供"全包式度假套餐"的旅行社,一切都为你安排好了,体验统一但可能缺少个性。而 KMP 则像是一个"机票+酒店"预订平台,给你极大的灵活性去组合不同航司和酒店,打造个性化的旅程。
-
Google 的战略:覆盖不同的开发场景和受众
- Google 内部不是一个单一的决策体。Flutter 团队和 Android 团队有各自的目标和受众。
- Flutter 吸引的是追求极致跨平台效率的开发者,包括初创公司、需要快速构建 MVP 的团队,以及希望 UI 在所有平台完全一致的场景。
- Kotlin Multiplatform (尤其是通过 Jetpack Compose Multiplatform)吸引的是现有的、庞大的 Android 原生开发生态。对于已经拥有成熟原生应用的大公司(如 Netflix, Airbnb),让他们用 Flutter 重写整个应用是不现实的。但让他们用 KMP 来逐步统一业务逻辑,却非常有吸引力。Google 支持 KMP,就是服务于这部分核心原生开发者,防止他们流失。
-
JetBrains 的动机:推广 Kotlin 语言
- KMP 的主要推动者是 JetBrains(Kotlin 的创造者)。他们的核心目标是让 Kotlin 成为一门真正通用的开发语言,而不仅仅是"更好的 Java"或"Android 语言"。KMP 是实现"Kotlin 无处不在"愿景的关键一步,允许开发者用 Kotlin 编写后端、Android、iOS、Web 甚至桌面应用。
-
Compose Multiplatform 的加入改变了游戏规则
- 最初 KMP 主要关注逻辑共享。但随着 Compose Multiplatform (基于 JetBrains Compose 的声明式 UI 框架)的成熟,KMP 现在也具备了与 Flutter 在 "共享 UI" 领域竞争的能力。
- 现在开发者有了两个选择:
- 选项 A(原生路线):用 KMP 共享业务逻辑,用 SwiftUI 和 Jetpack Compose 分别写原生 UI。获得最佳的原生体验。
- 选项 B(统一 UI 路线):用 KMP + Compose Multiplatform 同时共享逻辑和 UI。这类似于 Flutter,但使用的是 JetBrains 的声明式 UI 范式。
总结
- 选择 Flutter :当你需要最高效地 构建一个体验完全一致的跨平台应用,你的团队不介意学习 Dart 和新的 UI 范式,并且你对极致原生体验的要求不是排在第一位的。
- 选择 React Native:如果你的团队有强大的 Web 背景(React),需要利用 npm 的庞大生态,并且相信其新架构能解决性能问题。
- 选择 Kotlin Multiplatform :
- 当你需要渐进式地将共享逻辑集成到现有的原生应用中。
- 当你认为保持绝对的原生外观和体验至关重要。
- 当你的团队主要由 Android 开发者构成,希望最小化学习成本。
- 当你希望用 Kotlin 这一种语言覆盖前端和后端。
所以,KMP 不是要取代 Flutter,而是提供了一个不同的、互补的解决方案。Google 同时支持两者,是为了最大化地覆盖从追求"跨平台效率"到追求"原生体验和渐进式改进"的整个开发者光谱。这是一种"多线押宝,满足所有需求"的战略。
KMP + Compose Multiplatform 同时共享逻辑和 UI 如果使用这种方式在ios上是如何渲染的呢, 和ReactNative渲染成原生组件有什么区别
Kotlin Multiplatform(KMP)结合 Compose Multiplatform 可以在 iOS 上实现 UI 共享,但其渲染方式与 React Native(RN)有本质区别。以下是详细对比:
1. KMP + Compose Multiplatform 在 iOS 上的渲染方式
Compose Multiplatform 是 JetBrains 基于 Jetpack Compose(Android 的声明式 UI 框架)扩展的跨平台 UI 解决方案。它在 iOS 上的渲染方式如下:
(1) 基于 Skia 的自绘渲染(类似 Flutter)
- Compose Multiplatform 不依赖 iOS 原生组件 (如
UIView
或SwiftUI
),而是使用 Skia 图形引擎 直接在屏幕上绘制 UI。 - 这意味着:
- UI 渲染完全由 Compose 控制,不经过 UIKit/SwiftUI。
- 视觉一致性:iOS 和 Android 的 UI 外观完全一致(因为都是 Skia 绘制)。
- 性能接近 Flutter:没有 RN 那样的 JavaScript 桥接开销,但比纯原生 UI 稍慢(因为需要额外的 Skia 绘制层)。
(2) 与原生平台交互
- Compose Multiplatform 仍然可以调用 iOS 原生 API(如传感器、文件系统、通知等),通过 KMP 的
expect
/actual
机制 实现平台特定代码。 - 但 UI 部分是完全跨平台的,不映射到 iOS 原生组件。
(3) 示例代码结构
kotlin
// 共享的 Compose UI(Android 和 iOS 共用)
@Composable
fun Greeting(name: String) {
Text(text = "Hello, $name!")
}
// iOS 入口(通过 Compose Multiplatform 渲染)
fun MainViewController() = ComposeUIViewController {
Greeting("iOS")
}
- 在 iOS 上,Compose 会创建一个
UIView
,但内部使用 Skia 绘制,而不是 UIKit 组件。
2. React Native 在 iOS 上的渲染方式
React Native 采用 "JavaScript 描述 UI → 映射为原生组件" 的机制:
(1) 基于原生组件(UIKit/SwiftUI)
- RN 的 UI 组件(如
<View>
,<Text>
)最终会被转换成对应的 iOS 原生组件(UIView
,UILabel
)。 - 渲染流程 :
- JavaScript 代码定义 UI(JSX)。
- React Native 的 Shadow Tree(虚拟 DOM)计算出布局差异。
- 通过 Bridge/JSI(TurboModules) 将 UI 更新传递给原生端。
- iOS 使用 UIKit/SwiftUI 进行实际渲染。
(2) 优点
- 原生外观 :UI 组件是真正的
UILabel
、UIButton
,符合 iOS 设计规范。 - 性能较好(新架构) :
- 旧版 RN 依赖 Bridge(有延迟)。
- 新版 RN(Fabric)使用 JSI(JavaScript Interface) 直接调用原生代码,减少通信开销。
(3) 示例代码
jsx
// React Native 代码(JS)
function Greeting({ name }) {
return <Text>Hello, {name}!</Text>;
}
// iOS 端实际渲染的是原生 UILabel
- 最终在 iOS 上,
<Text>
会被转换成UILabel
,由 UIKit 渲染。
3. 关键区别对比
特性 | KMP + Compose Multiplatform | React Native |
---|---|---|
UI 渲染方式 | Skia 自绘(类似 Flutter) | 映射为原生组件(UIKit/SwiftUI) |
视觉一致性 | ✅ Android 和 iOS 完全一致 | ❌ 依赖平台原生组件,可能有差异 |
性能 | ⚡️ 较好(无 Bridge,但 Skia 有额外开销) | ⚡️ 新版(Fabric)接近原生,旧版有 Bridge 延迟 |
原生体验 | ❌ UI 不是真正的 UIKit 组件 | ✅ 使用真正的 UILabel 、UIButton |
热重载 | ✅ 支持(Compose 特性) | ✅ 支持(Fast Refresh) |
适用场景 | 需要 完全一致的 UI,且团队熟悉 Kotlin | 需要 原生外观,且团队熟悉 JavaScript/React |
4. 如何选择?
-
选 KMP + Compose Multiplatform:
- 你希望 UI 在 Android 和 iOS 上完全一致(不依赖平台原生样式)。
- 你的团队 主要使用 Kotlin,不想维护两套 UI 代码。
- 你愿意接受 Skia 渲染的轻微性能开销(类似 Flutter)。
-
选 React Native:
- 你希望 UI 符合 iOS/Android 原生设计规范(如 iOS 的模糊效果、Android 的 Material 3)。
- 你的团队 熟悉 JavaScript/React,不想学习 Kotlin。
- 你依赖 庞大的 npm 生态(如第三方 RN 模块)。
总结
- KMP + Compose Multiplatform 在 iOS 上使用 Skia 自绘,类似 Flutter,提供一致的 UI,但牺牲了一些原生体验。
- React Native 在 iOS 上使用 真正的 UIKit 组件,外观更原生,但依赖 JavaScript 桥接(新版 JSI 优化后性能接近原生)。
- 如果你的目标是最大化的代码共享 + 一致的 UI,Compose Multiplatform 是更好的选择。
- 如果你需要应用看起来和原生一样,React Native(或纯 KMP + 原生 UI)更合适。
KMP + Compose Multiplatform和Fultter一样, 在跨平台渲染上都是使用Skia自绘, 渲染引擎都是需要打包进去的, 那么对比fultter来说包体积都会增加, 并没有明显的优势吧
如果 KMP + Compose Multiplatform 采用和 Flutter 一样的 Skia 自绘方案,那么在包体积、渲染性能、跨平台一致性等方面确实和 Flutter 非常相似,甚至在某些方面可能还不如 Flutter 成熟。那么,KMP + Compose Multiplatform 的真正优势在哪里?为什么 Google/JetBrains 还要推动这个方案?
1. 包体积对比:KMP + Compose Multiplatform vs. Flutter
(1) 如果完全使用 Compose Multiplatform(Skia 自绘)
- Flutter :
- 必须打包 Dart VM + Skia + Flutter 框架 ,导致 基础包体积较大(Android ~4-5MB,iOS ~10-15MB)。
- 即使是一个简单的 "Hello World" 应用,也无法避免这个开销。
- KMP + Compose Multiplatform :
- 同样需要打包 Skia + Compose 运行时 ,包体积 接近 Flutter(目前甚至可能更大,因为 Compose Multiplatform 的优化不如 Flutter 成熟)。
- 例如,一个简单的 Compose Multiplatform 应用在 iOS 上可能增加 8-12MB(取决于优化程度)。
👉 结论 :如果完全依赖 Compose Multiplatform 做 UI,包体积确实和 Flutter 差不多,没有明显优势。
2. 那么 KMP 的真正优势是什么?
KMP 的核心价值在于 "灵活性" ,它允许开发者 按需选择共享逻辑还是共享 UI ,而 Flutter 强制你使用 Dart + Skia 自绘。具体来说:
(1) 你可以选择只共享业务逻辑,UI 仍然用原生
- KMP 允许你只共享 Kotlin 业务代码(网络请求、数据库、状态管理等),而 UI 仍然用 SwiftUI/Jetpack Compose 。
- 这样 不会引入 Skia 引擎 ,包体积增加很少(仅 Kotlin/Native 运行时,约 1-2MB)。
- 适用于 已有大型原生项目,想逐步迁移到跨平台,而不是全盘重写。
- Flutter 无法做到这点,你必须用 Dart 写所有逻辑和 UI,无法复用现有的 Swift/Kotlin UI 代码。
(2) 渐进式采用:从共享逻辑 → 共享 UI
- 阶段 1:先用 KMP 共享业务逻辑,UI 保持原生(最小化包体积影响)。
- 阶段 2:部分 UI 改用 Compose Multiplatform(如设置页面、内部工具页)。
- 阶段 3:核心页面仍然用原生 UI(如 iOS 的相机界面、Android 的深度定制 UI)。
- Flutter 无法这样渐进式采用,你必须全盘接受 Flutter 的渲染体系。
(3) 更好的原生互操作性
- KMP 可以无缝调用平台 API (通过
expect
/actual
),比 Flutter 的 Platform Channels 更类型安全、性能更好。 - 例如:
- 在 iOS 上直接调用
ARKit
,Android 上直接调用CameraX
,而共享代码只需要一个统一的接口。
- 在 iOS 上直接调用
- Flutter 需要通过 MethodChannel 调用原生代码,有一定的序列化开销。
(4) 对 Android 开发者更友好
- 如果团队已经是 Kotlin + Jetpack Compose 技术栈,迁移到 KMP + Compose Multiplatform 的学习成本极低。
- Flutter 需要学习 Dart 和全新的 Widget 系统,对 Android 原生开发者来说是一个较大的转变。
3. 什么情况下应该选 Flutter?
虽然 KMP + Compose Multiplatform 在某些场景下更灵活,但 Flutter 仍然是更好的选择,如果:
- 你需要最快的 UI 开发速度(Hot Reload + 丰富的 Widget 库)。
- 你的团队没有 Kotlin 经验,但熟悉 Dart 或愿意学习。
- 你希望 UI 在所有平台 100% 一致(Compose Multiplatform 还在发展,不如 Flutter 成熟)。
- 你的应用对包体积不敏感(比如非轻量级工具类应用)。
4. 总结:KMP + Compose Multiplatform vs. Flutter
对比维度 | KMP + Compose Multiplatform | Flutter |
---|---|---|
包体积(全 UI 共享) | 和 Flutter 接近(Skia 引擎) | 较大(Dart VM + Skia) |
包体积(仅共享逻辑) | ✅ 很小(1-2MB) | ❌ 必须全用 Flutter |
UI 渲染方式 | Skia 自绘(可混合原生 UI) | Skia 自绘(强制) |
开发体验 | 适合 Kotlin/Compose 开发者 | 适合 Dart/Flutter 开发者 |
跨平台一致性 | ✅ 可调整(自绘 or 原生) | ✅ 强制一致 |
适用场景 | 渐进式跨平台、已有原生代码库 | 全新应用、快速开发 |
最终建议
- 如果你已经有成熟的 Android/iOS 原生代码 ,想逐步共享逻辑,KMP 是最佳选择(可避免重写 UI)。
- 如果你从零开始一个跨平台应用 ,且不依赖原生代码 ,Flutter 仍然是更成熟、更快的选择。
- 如果你希望未来 Compose Multiplatform 能替代 Flutter,可以关注它的发展,但目前(2025年)Flutter 的生态和工具链仍然更强大。
KMP + Compose Multiplatform 的终极目标不是完全取代 Flutter,而是提供另一种更灵活的选择,特别是对 Kotlin 生态的开发者。🚀