一个欲儿的博客

一个欲儿的博客

KMP架构为什么可以跨端——只会安卓开发顺便学会了ios开发岂不爽翻了
2025-07-11

1. KMP 产生的原因

有个问题一直都有,如果你有一个购物的app,但是不同用户的手机的操作系统不一样,有苹果有安卓也有鸿蒙,所以你要开发三个app,并且培养三批人,但是其实很多东西是重复的, 比如业务逻辑是重复的,三端都要进行相同逻辑的处理,结果就写了三遍相同的业务逻辑,ui也是重复的,明明各个操作系统的ui其实长得大差不差,但是却写了三遍

谷歌这边发现了这个问题,开发了kmp架构,全称 Kotlin Multiplatform,从而实现一套ui,一套业务逻辑却可以编译出三个平台的代码

2. 利用官方Demo理解KMP

2.1 新建一个demo项目理解一下项目结构

用Android studio新建一个KMP架构的项目看一看

image.png

KMP是一个跨平台的架构,那么里面肯定会有各个平台相同的东西以及不同的东西,所以这个地方会有androidApp文件夹以及iosApp文件夹,鸿蒙我就先不写了,毕竟现在用鸿蒙跟49年入国军差不多,那么shared里面放的就是大家都可以复用的东西,比如说业务逻辑,以及ui


image.png

2.2 Kotlin特性之expect、actual

接下来再介绍一下kotlin这门语言的一个特性expect,actual

我们不得不承认,因为操作系统不同,所以肯定有些地方必须需要各个原生平台去进行不同的处理,而expect,actual就刚好可以完美解决这个问题,看一下官方给我们的案例

打开shared文件夹,可以看到三个Main,分别是commanMain以及androidMain和iosMain,这里面的设计思路就是,可以共用的我们放到commonMain里面去,因为各个端的不同导致有差异,必须要到各个端作出不同的处理的放到androidMain或者iosMain里面去,这个问题的解决办法就是通过expect,actual来解决的


image.png


2.3 官方Demo例子中的expect、actual

看一个官方的例子,比如说我们现在需要获取当前的平台是安卓还是ios

首先申明一个Platform接口,接口有一个属性叫name,再创建一个getPlatform方法,这个方法返回一个Platform接口

image.png


点击下图箭头所指的expect 旁边的 A一样的按钮,会提示你要跳转到哪个 actual


image.png

至于上图第一个是安卓,如果你问我为啥苹果叫iosMain但是安卓叫main,不叫androidMain,我没办法回答你,但是我能告诉你这个开发环境比较叫android studio

可以看到,安卓侧和苹果侧分别有一个AndroidPlatform、IOSPlatform继承了Platform,并通过各自的actual fun getPlatform() 返回了不同的结果

image.png

那么到这个地方kmp你就理解的差不多了,相同的业务逻辑写在shared里面去,需要各个端因为端差异所带来的不同就通过expect,actual去分别实现,这就是kmp的核心思想

3. Compose等UI框架等诞生

这个时候马上就有人想到了,那我界面是不是也可以通过这种方式去设计?比如说一个Text组件,安卓侧和苹果侧自己去实现就好了,ui样式布局等逻辑我仍然放在shared里面,你很聪明可以说是个天才

3.1 封装一个三端的ui组件

下面我举个例子。封装一个安卓和苹果公用的按钮组件

commonMain

import androidx.compose.runtime.Composable

expect fun PlatformButton(onClick: () -> Unit)

@Composable
fun GreetingWithButton(name: String) {
    PlatformButton { println("Hello, $name!") }
}

androidMain

import androidx.compose.material.Button
import androidx.compose.material.Text

actual fun PlatformButton(onClick: () -> Unit) {
    Button(onClick = onClick) { Text("Click me") }
}

iosMAin

import androidx.compose.material.Button
import androidx.compose.material.Text

actual fun PlatformButton(onClick: () -> Unit) {
    Button(onClick = onClick) { Text("Tap me") }
}

按照这个基础原理,谷歌和腾讯字节等一些大厂以及开发出了好多kmp的ui框架,比如说谷歌自己的Compose,以及Tencent的kuikly,大家ui直接用框架,不用再做分别实现,业务逻辑直接放到androidMain和iosMain,可以说非常方便,只需要会其中一个另外几个平台都可以开发

4. 编译和调试

最后来说调试和编译的问题,右上角选择不同的调试方式就可以打开不同的操作平台去运行对应的app,包括编译的时候也可以通过expect,actual去找自己操作系统需要的内容去进行编译

image.png

发表评论: