Kotlin在跨平台中的跨平台开发
而在iOS那边,编译出来的framework可以直接在Swift里调用,而且由于Kotlin和Swift在语法上的相似性(比如都是空安全设计),两边工程师协作起来基本没有理解障碍。在KMP项目里,你会建一个叫shared的Common模块,这里面写的Kotlin代码是可以编译成JVM字节码、Native二进制文件甚至JS的。它不像Flutter那样激进地重塑整个开发生态,而是提供了一种渐进式的跨平
说实话,我之前对Kotlin的认知还停留在“更好的Java”这个层面,虽然知道它能写安卓,但要说跨平台……总觉得差点意思。抱着死马当活马医的心态,我决定探探这条路到底行不行。
结果不试不知道,一试直接打开了新世界的大门。Kotlin Multiplatform(简称KMP)这玩意儿的设计思路确实有点东西。它不像某些框架那样强行用一套UI打天下,而是很聪明地只共享业务逻辑。简单来说,就是让你用Kotlin把那些底层的网络请求、数据解析、缓存处理这些脏活累活一次性写好,然后各自平台的UI爱怎么画就怎么画。
刚开始我还在琢磨这共享代码该怎么组织,后来发现人家早就想好了。在KMP项目里,你会建一个叫shared的Common模块,这里面写的Kotlin代码是可以编译成JVM字节码、Native二进制文件甚至JS的。比如我们项目里的用户登录模块,网络请求、参数加密、token解析这些核心逻辑全部放在common里,然后安卓这边直接当普通库引入,iOS那边则编译成framework给Swift调用。
这里有个特别巧妙的设计——expect/actual机制。比如说设备信息获取,在common里你只需要声明expect fun getDeviceModel(): String,这就是告诉编译器“我这功能需要平台实现”。然后在androidMain里写actual fun getDeviceModel(): String = Build.MODEL,在iosMain里写actual fun getDeviceModel(): String = UIDevice.currentDevice.model。这种设计既保证了接口统一,又给了各平台充分的自由度,比硬塞给你一套兼容方案要优雅多了。
实际开发中最让我惊喜的是和平台生态的融合程度。在安卓这边,Kotlin代码可以直接调Android SDK,配合Coroutines做异步处理简直行云流水。而在iOS那边,编译出来的framework可以直接在Swift里调用,而且由于Kotlin和Swift在语法上的相似性(比如都是空安全设计),两边工程师协作起来基本没有理解障碍。我们iOS同事原话是:“这比让我去改RN的JavaScript顺眼多了。”
不过踩坑也是少不了的。初期最头疼的是编译速度问题,特别是在iOS这边调试时,每次修改共享代码都要重新生成framework。后来发现可以通过合理模块划分来缓解——把频繁变动的业务逻辑和稳定的基础工具分开,只编译变更的部分。还有就是第三方库的选择,虽然像Ktor、sqlDelight这些官方推荐的库确实好用,但遇到某些特定需求时,还是得自己动手写expect/actual来封装平台原生库。
说到现在KMP的生态,感觉已经过了“能不能用”的阶段,正在向“好不好用”进化。JetBrains自家出的Compose Multiplatform更是把跨平台玩出了新高度,现在连UI都可以共享了。不过在我们当前项目里,还是坚持只共享业务逻辑,毕竟现有的原生UI团队已经很成熟,没必要全盘推翻。
经过这个项目,我算是明白为什么越来越多团队开始尝试KMP了。它不像Flutter那样激进地重塑整个开发生态,而是提供了一种渐进式的跨平台方案——你可以先从工具类模块开始试水,慢慢扩展到核心业务,这种低风险的迁移路径对已有项目特别友好。
最后给正在观望的同学几点实在建议:如果是全新项目,强烈推荐直接上KMP架构;如果是存量项目改造,建议从网络层或数据层开始逐步迁移。记得提前规划好模块划分,别把所有代码都堆在一个common模块里。还有,团队里最好有个对Gradle构建流程熟悉的人,前期能省不少事。
回头看这个项目,从最初的双平台代码复制粘贴到现在的核心逻辑一套代码,开发效率提升真不是一点半点。至少现在听到产品经理说“安卓和iOS要同时上线”时,我能淡定地回一句:“没问题,咱们KMP见。”
更多推荐



所有评论(0)