Kotlin Multiplatform(简称KMP)这两年热度确实高,我在自己的团队里从最早“只敢拿一个非核心模块试水”,到后来把账号、网络层、数据存储全部下沉到共享代码,整个过程踩了不少坑,也搞清楚了很多文档里没写透的细节。这篇内容我尽量把KMP从原理到落地讲完整:它到底帮你解决了什么问题、项目结构应该怎么搭、iOS端怎么接入、哪些环节容易翻车,以及我实际使用一年后的真实感受。适合正在做双端开发的Android/iOS工程师,或者正打算把重复业务逻辑抽出来的团队参考。
1. 技术选型背后的真实诉求
1.1 KMP最核心的定位:共享逻辑,而非共享一切
很多人第一次听Kotlin Multiplatform,会误以为它和Flutter、React Native一样,是一套代码同时搞定两个平台的全部开发。这个理解从一开始就有偏差。KMP的核心目标是只共享业务逻辑层,也就是网络请求、数据解析、状态管理、数据库操作、权限判断这些与UI无关的部分,而UI仍然由各端原生实现。
这样设计的好处很直接:UI层是移动应用中变化最频繁、平台耦合最深的层次,强行共享UI往往意味着引入一套抽象渲染层,一旦遇到复杂交互或平台特殊行为,调试成本会成倍上升。KMP把共享边界划在“逻辑”而不是“界面”,本质上是选择了最稳妥、收益最可控的那一部分做复用。
我在团队里经常用一个比喻:Flutter是“连装修一起包了”,KMP是“只把承重墙和管道做好,装修各自来”。这两种思路没有绝对优劣,但如果你手里已经有一套成熟的原生UI组件库,或者产品对交互体验要求极高,KMP这种渐进式改造的路径会平滑得多。你可以只抽一个工具类模块、再抽网络层、再抽数据层,每一步都有明确的验收标准,不必经历“全量重写”的阵痛。
1.2 为什么我没有选Flutter或React Native
这个问题几乎每个决定用KMP的团队都会被问。我自己的判断逻辑是这样的:如果团队从零起步、缺少原生开发积累、产品以简单页面为主,Flutter确实能带来极高的交付效率。但如果你维护的是一个已经运行多年的原生应用,里面沉淀了大量自定义控件、系统能力调用、甚至部分C++底层库,那么“UI全部重做”的风险就非常大了。React Native则受限于桥接层性能,以及依赖生态版本管理的复杂度,在大型项目里同样会面临不少隐性成本。
KMP最大的吸引力在于保护原生投资:现有Android代码可以继续使用,现有iOS Swift/Objective-C代码也可以继续使用,新增能力或重构业务时再用KMP编写共享逻辑。这种共存能力让团队不需要做“二选一”的决定,而是可以逐步扩大共享范围。而且共享代码最终编译成Android的字节码和iOS的Native framework,调用方式对两端都是“原生”的,不会有解释执行或桥接带来的明显性能损耗。
当然我也要承认KMP的短板:它在UI层面的共享方案Compose Multiplatform成熟度还在爬坡,如果你期待“一套UI代码两端跑”,KMP目前的体验不如Flutter顺畅。所以KMP真正的应用场景是“业务逻辑重、UI差异大”的项目,用它的收益才最明显。
1.3 不适合上KMP的情况
不是所有项目都应该引入KMP。我总结了几类不太适合的场景,如果你遇到类似情况,建议先缓一缓。
- 纯Demo、原型、短期外包项目:KMP的学习成本、工程配置成本不算低,如果项目生命周期很短,省下来的逻辑复用可能覆盖不了成本。
- 团队没有Kotlin基础:KMP的共享代码是用Kotlin写的,虽然Kotlin和Java/Swift都有相似性,但如果整个团队要从零学语言同时又要学跨平台框架,学习曲线会比较陡。
- 业务逻辑极简单:如果应用只是几个展示页面、几乎没有复杂状态和网络层,KMP带来的抽象反而显得笨重。
- 高度依赖系统私有API:部分应用和系统能力深度耦合,比如频繁使用CoreBluetooth配合特定的iOS私有框架、或者依赖Android的AIDL绑定系统服务,这类代码很难抽成共享层。
判断标准我认为就一条:你能不能在两个平台里圈出一个足够大、且相对稳定的纯逻辑领域。 如果能,KMP的价值就很大;如果逻辑本身很少,它就是个负担。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. KMP核心原理详解
2.1 一套代码,多端产物
KMP能实现跨平台共享,底层靠的是Kotlin编译器针对不同目标平台生成不同产物。我们平时写的Kotlin代码在Android上会被编译成JVM字节码,在iOS上则通过Kotlin/Native编译器编译成原生机器码,最终封装成一个Apple Framework,由Xcode工程链接使用。在这两种情况下,源代码是同一份,编译器却完全不同。
这个设计有一个非常大的好处:共享代码里可以调用Kotlin标准库、协程、序列化等跨平台库,这些库在不同平台上都有对应的实现。你不需要像C++那样自己处理平台差异,也不需要在运行时搞一个巨大的解释器。Kotlin/Native还提供了一套底层的平台互操作机制(cinterop),允许你直接调用Objective-C和C的系统API,这意味着共享层虽然以Kotlin为主,但并没有被隔离在“小程序沙箱”里,需要时仍然能触及系统能力。
我刚开始接触KMP时有个明显的困惑:既然Shared模块能编译成iOS Framework,那它是不是只能在iOS上用?其实KMP的编译目标远不止这两端,它还能编译成JavaScript(用于Web前端)和桌面平台的原生二进制。也就是说你写一份业务逻辑,理论上可以覆盖Android、iOS、Web、Desktop四个方向,只
