Kotlin Multiplatform
☆ KMP 是跨端趋势话题。你有 Android + iOS 基础,可以把它讲成“共享业务逻辑,保留原生体验“的跨端判断力。
一、KMP 解决什么问题
KMP 不是用一套 UI 替代所有平台,而是优先共享业务逻辑、网络、数据、算法、领域模型,UI 仍可保持原生。
二、expect / actual 机制
公共代码声明 expect,各平台提供 actual 实现。
// commonMain
expect class DeviceInfoProvider {
fun deviceModel(): String
}
// androidMain
actual class DeviceInfoProvider {
actual fun deviceModel(): String = android.os.Build.MODEL
}
三、推荐分层
| 层 | 是否适合共享 | 说明 |
|---|---|---|
| domain/model | 很适合 | 业务规则稳定 |
| data/network | 适合 | Ktor/serialization 可共享 |
| platform capability | 部分适合 | 用 expect/actual 封装 |
| UI | 看项目 | Compose Multiplatform 或原生 UI |
四、和 Flutter / React Native 的区别
KMP 更偏共享逻辑,不是强制统一 UI;Flutter/RN 更偏统一 UI 技术栈。选择取决于团队能力、UI 一致性诉求、原生能力复杂度。
五、与 iOS 的互操作
KMP 可生成 framework 给 iOS 调用,但要注意 Swift/Objective-C 暴露、协程到 iOS async 的桥接、异常模型、包体积和调试体验。
六、工程结构与 source sets
KMP 面试不能只讲 expect/actual,还要能说清工程结构。
shared
├─ commonMain # 领域模型、UseCase、Ktor API、序列化、算法
├─ androidMain # Android Context、Keystore、Room/平台能力封装
├─ iosMain # iOS Keychain、NSURLSession/平台能力封装
└─ commonTest # 共享业务规则测试
常见库选择:Ktor 做网络、kotlinx.serialization 做序列化、SQLDelight 做跨端数据库、Koin/Kodein 做轻量 DI。选择时要看 iOS 调试、包体积、团队熟悉度和长期维护。
七、iOS 互操作高频追问
| 追问 | 稳妥回答 |
|---|---|
suspend 怎么给 Swift 用? | 可桥接到 async/await 或包装 callback,要统一错误和取消语义。 |
| Flow 怎么暴露? | 不要直接把复杂 Flow 泄漏给 Swift,可包装成 observable/callback/async sequence 风格接口。 |
| 泛型/密封类/异常怎么办? | Swift 暴露不总是自然,公共 API 要设计得 Swift 友好。 |
| 调试难不难? | shared 层能测,但跨边界调试、符号、崩溃归因和构建缓存要治理。 |
八、把 Android SDK 改成 KMP SDK 怎么设计
答题模板:
- 先拆边界:哪些是纯业务/协议/算法,哪些依赖 Android 系统能力。
- commonMain 放模型、协议、风控规则、网络 DTO、加密前的业务流程。
- 平台能力用 expect/actual 封装,如设备信息、Keychain/Keystore、文件路径、日志。
- iOS 暴露一层 Swift 友好 facade,不要把内部复杂协程/Flow 类型直接外泄。
- CI 同时跑 Android unit test、commonTest、iOS framework 构建和最小集成 demo。
- 风险评估:包体、构建时间、Native 崩溃定位、团队 owner、版本兼容。
高频面试题
Q1:KMP 适合什么场景? 答:适合共享业务逻辑、协议、数据层和算法;如果项目主要难点是高度定制 UI 或平台能力差异很大,要谨慎。
Q2:KMP 和 Flutter 怎么选? 答:想统一 UI 且团队接受新渲染栈可考虑 Flutter;想保留原生 UI、共享核心逻辑可考虑 KMP。
Q3:expect/actual 的意义是什么? 答:公共层定义平台能力抽象,各平台提供实际实现,既复用业务逻辑又不牺牲平台差异。
Q4:KMP 落地最大风险是什么? 答:不是语法,而是工程治理:iOS 暴露是否自然、构建/CI 是否稳定、跨端调试和崩溃归因是否可控、团队是否有人长期维护 shared 层。没有 owner 时,KMP 共享层容易变成两端都不敢改的黑盒。
易错点 / 追问
- 不要说 KMP 能无成本一套代码跑所有端。
- 不要把平台差异强行塞进 commonMain。
- iOS 调试、构建、二进制大小都要提前评估。