写点什么

Kotlin Multiplatform 评估:跨平台开发中的优势与权衡

作者:Rachit Jain

  • 2025-09-03
    北京
  • 本文字数:4876 字

    阅读完需:约 16 分钟

大小:2.44M时长:14:14
Kotlin Multiplatform评估:跨平台开发中的优势与权衡

引言

“一致性是关键”这句话经常在分布式系统环境中听到,但在移动和 Web 应用开发中也同样适用。在一个需要在多个平台上无缝运行单一应用程序的世界里,保持跨平台的一致性不仅仅是一个目标,而且是必要的。多年来,开发人员一直面临着一个艰难的选择:为每个平台构建独立的原生应用程序,还是采用跨平台框架。

 

传统上,为 Android 和 iOS 开发原生应用程序需要双倍的资源:两个代码库、两个工程团队,以及双倍的努力来保持功能和业务逻辑的同步。当应用程序需要一致的 UI 和相同的业务逻辑时,它们会共享驱动它们的代码。

 

这种需求催生了像 Flutter 和 React Native 这样的强大的跨平台工具。虽然这些工具非常有效,但它们通常伴随着重大的权衡。它们通常要求开发人员使用不同的 UI 渲染引擎(Flutter)或使用桥接(React Native),与原生代码相比,这可能会带来性能损失。

 

在这种情况下,KMP 提供了一种独特的方法。KMP 不是取代原生平台 SDK,而是与它们一起工作,允许开发人员通过直接使用平台 API 的典型访问方式来共享通用代码。具体来说,这意味着你可以创建一个 KMP 应用程序,通过使用原生 UI 工具包,保留每个平台的外观和感觉,类似于 React Native。但你还可以使用 Compose Multiplatform 走 Flutter 的路子,共享 UI 实现,尽管代价是它在 iOS 上看起来不那么“原生”。

 

总之,当与 Compose Multiplatform 搭配使用时,KMP 提供了一个引人注目的用例:编译成原生代码以获得出色的性能,类似于 Flutter,并保留使用原生 UI 工具包的选项,这种灵活性也存在于 React Native 中。

 

KMP正在成为跨平台开发的一种强大的替代方案,提供了一条共享代码的路径,而不会牺牲原生应用程序的性能和感觉。有了 KMP 作为替代方案,它也带来了自己的一系列权衡,本文将深入探讨这些问题。

 

虽然本文主要关注 Android 和 iOS 开发,但 KMP 的愿景更加广泛。它可以用来构建桌面应用程序(Windows、macOS、Linux)、Web(使用 Kotlin/JavaScript)甚至服务器端应用程序,所有这些都来自相同的共享逻辑。

 

什么是 Kotlin Multiplatform(KMP)?

KMP 允许开发团队在不同的平台上编写和共享代码,同时借助 Compose Multiplatform 提供构建原生用户界面的选项。它不是一个“全或无”的框架,也并不是简单地抽象掉平台。相反,它是一个复杂的工具,允许你共享应用程序中平台无关的部分,同时保持平台特定部分的原生特性。Android 开发者可以在 Kotlin 中编写 UI 代码,而 iOS 开发者可以在 Objective-C 或 Swift 中编写 UI 代码。但这并不意味着 UI 只能使用原生接口构建,这是一个重要的区别。KMP 提供了灵活性,允许你按照自己的方式构建用户界面。

 

KMP 的工作原理

KMP 具有特定的项目结构和 expect/actual 机制,使其能够跨平台工作。一个典型的 KMP 项目被划分为如下几个模块:

 

  • commonMain 包含通用代码。这段代码编译一次,并在所有目标平台上共享。你可以将业务逻辑、网络调用等放在这个模块中。

  • androidMain 包含 Android 实现。Android 设备的 UI 可以在这个模块中用 Kotlin 编写。

  • iosMain 包含 iOS 实现。iOS 设备的 UI 可以在这个模块中用 Swift 或 Objective-C 编写。

 

expect/actual 关键字是公共实现和平台特定实现之间的桥梁。在 commonMain 中,你可以期望存在一个类或函数,定义其 API。然后,在 androidMainiosMain 中,你为该声明提供实际的特定于平台的实现。例如,你可能会期望一个函数在 commonMain 中生成一个唯一的标识符(UUID),然后分别在 androidMain 中使用 Android 的 UUID.randomUUID() 和在 iosMain 中使用 iOS 的 NSUUID().uuidString 提供实际的实现。

 

使用上述结构,可以同时为跨平台构建应用程序,而不会牺牲应用程序的性能。

 

Kotlin Multiplatform 的优势

降低工程成本

统一架构并允许相同的开发人员为多个平台编写代码可以显著降低工程成本,这是理所当然的。通过将业务逻辑、网络等放在共享的 commonMain 模块中,你消除了两次实现和测试同一功能的需求。这将直接减少重复工作。这也减少了特定于平台的错误,从而产生更健壮和可靠的产品。此外,它简化了质量保证流程,因为核心逻辑只需要测试一次。需要重点指出的是,这个优势也时由 Flutter 和 React Native 提供的。在这方面,KMP 与其他技术相比没有优势。

 

原生性能

与其他跨平台工具不同,KMP 让开发人员使用平台的原生工具构建用户界面。共享的 Kotlin 代码被编译成目标平台的预期格式,对于 Android 是 JVM 字节码,对于 iOS 是原生二进制文件。与 React Native 不同,运行时没有解释层,这使得应用程序能够实现类似原生的性能。

 

逐步采用

虽然 Flutter(使用 Dart)和 React Native(使用 Typescript 或 Javascript)需要“全有或全无”的采用方式,但 Kotlin Multiplatform 却不是这样。它可以逐步引入到代码库中,使过渡更加平滑。你可以将 KMP 逐步引入到现有的原生应用程序中,这有助于确保在整个过程中保持稳定。一个常见的起点是将单个功能或特定层迁移到共享的 KMP 模块中。

 

Android 团队的自然发展

随着谷歌正式将 Kotlin 作为 Android 开发的主要语言,大多数 Android 团队已经在使用它进行构建了。对于这些团队来说,过渡到 KMP 的进入门槛非常低。

 

Flutter、React Native、KMP:比较

尽管这三种技术都支持跨平台开发,但它们的操作原则不同,特别是在用户界面(UI)和总体理念方面。下面的表格总结了我们上面讨论的主要区别。

特性

Flutter

React Native

Kotlin Multiplatform (KMP)

语言

Dart

JavaScript / TypeScript

Kotlin

UI渲染

使用Skia引擎渲染自己的UI

通过JS桥接控制原生UI组件

可以使用原生UI(SwiftUI/Compose)或共享UI(Compose Multiplatform)

性能

优秀,编译成原生代码,没有桥接

良好,但JavaScript桥接可能是瓶颈

优秀,编译成平台原生格式,没有桥接

采用

全面承诺

全面承诺

逐步采用

KMP 和 Compose Multiplatform 在 iOS 上的当前状态

在历史上,Kotlin 从未被用来开发过 iOS 应用程序。但是有了 KMP 和 Compose Multiplatform,现在这是可能的了。

 

长期以来,iOS 上的 KMP 故事都是“共享你的逻辑,原生构建你的 UI”。虽然这是一种强大的方法,但它仍然意味着 UI 开发是一个特定于平台的任务。随着 1.8.0 稳定版本的发布,这种情况发生了变化。截至 2025 年 5 月 6 日,面向 iOS 的 Compose Multiplatform 已经达到了一个稳定的、生产就绪的里程碑

 

这一里程碑对 KMP 生态系统来说是一个巨大的胜利。Jetpack Compose 是谷歌面向 Android 的现代声明式 UI 工具包。有了 Compose Multiplatform,你现在可以使用完全相同的 Kotlin 代码来定义 Android 和 iOS 的 UI。这意味着你不仅可以共享业务逻辑,还可以共享 UI 本身。该框架现在提供了与 iOS 版本的 Jetpack Compose 相同的功能,使其成为新项目的可行选择。在我看来,Compose Multiplatform 1.8.0 不仅对 iOS 开发有价值,而且还实现了 KMP 的真正价值主张,开发者现在可以引导整个应用程序了。

 

此外,对于某些屏幕使用原生 Swift/UIKit 进行混合匹配,而对于其他屏幕使用 Compose,提供了最大的灵活性。为此,你依赖于框架提供的特定包装器组件,这些组件利用了 SwiftUI/UIKit 互操作性。例如,要在原生 SwiftUI 应用程序中使用 Compose Multiplatform 屏幕,将你的可组合 UI 包装在 ComposeUIViewController 中。然后,在 SwiftUI 代码中,创建一个 UIViewControllerRepresentable 协议的结构,它将管理控制器。要在 Compose UI 中使用原生 SwiftUI 屏幕,将 SwiftUI 视图托管在 UIHostingController 中,该控制器可以直接嵌入到 Compose 布局中,使用 UIKitView 可组合项。

 

总的来说,每当采取混合和匹配的方法时,都会有一些控制器可以将不同的 UI 方法嵌入到应用中。虽然可能涉及到陡峭的学习曲线,但这种方法仍然提供了显著的灵活性。

 

Kotlin Multiplatform 的大用户

KMP 不仅仅是一个理论概念,它正在被奈飞、麦当劳和飞利浦等大型全球公司用于生产。

 

奈飞(Netflix)被认为是 KMP 的早期和重要采用者,因为他们在 2020 年 10 月就采用了它。他们使用 Kotlin Multiplatform 统一了应用程序的业务逻辑,确保所有用户的功能行为一致,无论设备如何。他们还将其用于他们的内部“Prodicle”应用程序,该应用程序支持电视和电影项目的实体制作。

 

我们的 Android 和 iOS 工作室应用程序具有共享的架构,两个平台上都有相似或在某些情况下相同的业务逻辑——Netflix

奈飞能够实现 50%的代码与底层平台的解耦。展望未来,奈飞还谈到了将他们的工作室应用程序发展成一个薄 UI 层的可能性,该层共享用 KMP 编写的相同业务逻辑。

 

麦当劳(McDonald)在应用程序中引入应用内支付时,就开始使用 KMP(早期版本中称为 KMM)。在验证了这种方法之后,他们将 KMP 的使用扩展到了其他服务中。

 

将 KMM 集成到应用程序流程中,除了在每个平台上正确显示本地化数据和产品所需的业务逻辑之外,还允许我们在一个位置内开发解析和存储逻辑——McDonald’s.

 

例如,为了处理不同国际地区的客户的不同需求,他们将管理特定地区产品和数据的逻辑集中到一个共享的 KMP 模块中。在这里,他们将 KMP 引入到他们的业务逻辑中,以处理特定于语言环境和设备的产品和数据。

 

最终,麦当劳重写了他们的整个应用程序以使用 KMP。通过这一战略转变,他们将独立的Android和iOS团队合并成一个更统一、更高效的移动团队

 

飞利浦(Philips)在 2018 年采用了 KMP,作为从原生开发转向的一种方式。飞利浦利用 Kotlin Multiplatform 开发一个共享的 SDK,用于设备通信和数据同步,以实现他们的连接消费和个人健康产品的移动应用连接,如牙刷和空气净化器。使用 KMP,他们能够保持共享的业务逻辑。

 

BLE 接口的差异太大了,以至于你无法设计出一个同时匹配它们的设计。因此,我们将继续保持以原生方式进行这部分工作——Philips

 

他们最初在蓝牙低功耗(BLE)的蓝牙 API 上遇到了一些问题。为了解决这个问题,他们保留了蓝牙堆栈的原生实现,这表明开发人员并没有将所有的代码库都锁定在 KMP 中。

 

我们可以看到,随着越来越多的公司采用 KMP,我们看到 KMP 正在开始兴起。公司开始缓慢起步,然后随着他们开始看到好处,他们的用例也在增加。我建议你查看所有这些案例研究,因为我在本文中只提到了其中的一些精选示例。

 

挑战和考虑因素

虽然 Kotlin Multiplatform 为跨平台开发提供了一个有希望的方法,但必须承认 KMP 当前还有局限性。

 

生态系统的成熟度

一个主要挑战是与 Flutter 和 React Native 等现有工具相比,开发者社区和支持生态系统较小。虽然核心功能得到了很好的支持,但寻找 KMP 就绪的库以满足高度特定的需求,如高级蓝牙交互或后台服务,可能仍然需要编写平台特定的实现,正如我们在飞利浦案例中看到的。这有时意味着开发者需要创建自己的原生解决方案包装器,这并不理想。

 

iOS 团队的学习曲线

对于 iOS 团队来说,采用 Kotlin 和 Gradle 构建系统可能会有一个学习曲线,这些在 Android 生态系统中是标准的,但对大多数 iOS 开发者来说是新的。

 

Kotlin/Native 的互操作性

Kotlin/Native 与 Swift/Objective-C 之间的互操作性有其自身的限制。Kotlin/Native 通过 Objective-C 与 Swift 提供间接互操作性。例如,一些 Kotlin 语言特性可能在 Objective-C 中没有直接等价物,这就要求开发人员在开发过程中了解这些差异。这个要求可能会成为一大障碍,因为大多数开发人员在开始开发之前并不知道这一点。泛型就是一个例子,其中类型信息在翻译过程中丢失。开发人员需要注意传递的类型,并围绕此进行检查。

 

工具和开发工作流程

虽然工具正在持续改进,但它仍然不如当前的原生开发工具那样无缝。JetBrains 正在积极开发 KMP 插件,让它变得更容易。

 

尽管面临的挑战很多,也不容忽视,但这个环境正在迅速变化。公平地说,对 Kotlin 本身的支持已经成熟,并且还在继续增长,KMP 社区是这一趋势的直接受益者。随着采用率的增加,共享知识和开源库的数量也将增加。

 

结论

跨平台开发一直是在开发效率与原生性能和外观感觉之间权衡的练习。有了 Kotlin Multiplatform,这些权衡在某种程度上减少了。你获得了共享代码库的效率,同时提供了几乎与原生一样好的性能。

 

虽然核心功能得到了很好的支持,但寻找 KMP 就绪的库以满足高度特定的需求,如高级 BLE 交互或后台位置服务,可能仍然需要编写平台特定的实现。这确实带来了一个问题,因为需要所有这些功能的应用不能仅使用 KMP 构建。但正如前面提到的,这是一个迭代过程,由于 KMP 开发是活跃的,因此将引入更好的支持。

 

KMP 提供了一条灵活而强大的前进道路,允许团队为多平台世界构建一致的、高性能的应用程序,而无需放弃其原生根基。对 Kotlin 的支持很强大,其多平台能力只会从这里开始增长。

 

原文链接:

https://www.infoq.com/articles/kotlin-multiplatform-evaluation/

2025-09-03 15:001

评论

发布
暂无评论

帮助小团队实现大梦想 | Atlassian 云产品免费使用

Atlassian

使用 Generic Webhook Trigger 触发 Jenkins 多分支流水线自动化构建

jerry.mei

DevOps 持续集成 jenkins CI/CD 持续交付

java8的parallelStream提升数倍查询效率

网站,小程序,APP开发定制

java8

AOP有几种实现方式?

八苦-瞿昙

技术 随笔杂谈 aop 代理 框架

如何编写可怕的 Java 代码?

武培轩

Java 编程 程序员 后端

了不起的 Webpack Scope Hoisting 学习指南

Geek_z9ygea

Java 大前端 webpack

创业使人成长系列 (3)- 如何取个好名字

石云升

创业 成长 取名

ARTS 04 - 使用 Gitlab + Generic Webhook Trigger 触发 Jenkins 自动化构建

jerry.mei

算法 ARTS 打卡计划 CI/CD 函数式编程 Elixir

关于架构的几件小事:架构概述(1)

北风

架构 架构设计 架构师 架构设计原则

手把手整合SSM框架

JavaPub

[译] 图说前端-图解 React Native

梦见君笑

大前端 漫画编程

如何使用预测性指标衡量敏捷转型的成功?

Atlassian

敏捷开发 开发工具 Atlassian Jira

[译] 图说前端-组件、Prop 和 State

梦见君笑

大前端 React 漫画编程

JavaScript 混淆与逆向必读之 AST 节点类型名词基础

穿甲兵

Java

海南的七星彩网站系统盘口代码解析

网站,小程序,APP开发定制

代码

架构师训练营第六周学习总结

CATTY

工程规约 - maven统一管理

Man

maven DevOps 工程规约

架构师训练营第六周学习总结

张明森

要不要做一个gif动态图玩一下?

诸葛小猿

GIF ScreenToGif 动态图

如何在 Go 中写出高效的单元测试

Grafana 爱好者

testing slideshare Go 语言

[译] 图解前端-深入理解 Props 和 State

梦见君笑

大前端 React 漫画编程

架构师训练营第六周作业--doris临时失效时序图

CATTY

时序图

万字详解加拿大央行CBDC分析报告

CECBC

架构师课程第六周 作业

杉松壁

阿里花500万年薪招天才黑客?官方回应:这种人得交给警察

程序员生活志

黑客 阿里

U盘+grub2安装centos8实战

程序饲养员

[译] 图说前端-图解 React

梦见君笑

大前端 React 框架

技术解读:单集群如何做到2万+规模

数据湖洞见

大数据 FusionInsight 华为云 大集群

vue项目发布时去除console语句

网站,小程序,APP开发定制

每周学习总结 - 架构师培训 6期

Damon

架构师训练营第六周作业

talen

Kotlin Multiplatform评估:跨平台开发中的优势与权衡_软件工程_InfoQ精选文章