聊聊Compose跨平台与KMM
上个月JetBrains发布了Compose Multiplatform for iOS Alpha版本,这让许多热爱跨平台的开发者喜出望外。本次分享将通过以下几点来介绍Compose Multiplatform与KMM,让我们一起体验Kotlin跨平台的魅力。
- Compose Multiplatform与KMM的关系
- Compose Multiplatform与KMM的实践
- 开发者该如何选择
需要说明的是,本次分享从使用角度出发,作为跨平台技术的普及,不涉及底层原理。
Compose Multiplatform与KMM的关系
要理解Compose Multiplatform与KMM的关系,我们分别了解它们是什么。
KMM是什么
KMM的全称是Kotlin Multiplatform Mobile,与之对应的是KMP—Kotlin Multiplatform Project。KMM更像是营销术语,实际指的是Kotlin跨平台,不仅限于移动端。KMM可以简化多平台应用程序的开发,允许在iOS、Android、Desktop与Web应用程序之间共享业务逻辑的通用代码,并在必要时编写特定于平台的代码。因此,KMM只负责跨平台下的业务逻辑部分,比如数据层、网域层等都可以使用KMM来完成公共业务逻辑。
在KMM早期推出时,Compose Multiplatform尚未发布,因此许多开发者认为KMM较鸡肋,因为移动端主要工作在于UI编写。然而,这种观点并不正确,许多业务逻辑如日志系统、埋点等使用KMM非常有利。后来Compose Multiplatform的出现弥补了KMM的短板。
Compose Multiplatform是什么
Jetpack Compose是Android官方推出的声明式UI框架,Compose Multiplatform是由JetBrains维护的Compose跨平台框架,专注于UI跨平台,同样支持iOS、Android、Web、Desktop等。有了Compose跨平台,便弥补了KMM的缺陷。
虽然Compose Multiplatform与KMM在版本更新和维护者上不同,但Kotlin底层对Native、JS的支持是Compose Multiplatform的基础。因此,我更希望它们未来能合并,统称为Kotlin全平台。现在你已经了解了KMM与Compose Multiplatform的关系,接下来我们看它们的实践。
Compose Multiplatform与KMM的实践
由于Compose Multiplatform复用UI,KMM复用业务逻辑,我们分别来看如何实践。
实践KMM
KMM用于实现业务逻辑部分,这里以Android和iOS两端为例。需要重申的是,Compose Multiplatform与KMM可以独立使用,即在使用KMM时可以分别写原生UI,在使用Compose Multiplatform跨平台时可以分别实现其他端的业务逻辑。
创建项目
在Android Studio中,我们可以借助Kotlin Multiplatform Mobile插件快速创建支持KMM的项目。安装好插件后,直接创建项目时填写模块信息。创建好的项目目录结构包括androidApp、iOSApp和shared模块,shared模块存放Android、iOS公共业务逻辑。KMM插件只创建了Android和iOS的源集,如果想添加其他平台,可以自己创建文件夹并指定目标平台。
公共业务逻辑
双端完全共用的逻辑直接放在commonMain文件夹下,开源库的依赖写在commonMain目录下。例如添加网络请求库Ktor和序列化的依赖,因为Ktor是Kotlin推出的网络请求库,是跨平台的最佳选择。我们可以定义getData方法来获取数据,然后各自在Android或iOS的UI代码中接收数据并展示。这样就实现了双平台简单的数据请求例子。
社区对KMM的支持
目前官方许多库已经支持跨平台,比如网络请求框架Ktor、依赖注入Koin和序列化组件等。对Android开发者来说,最友好的消息是从去年10月份开始Jetpack也开始支持跨平台,不过当前支持的组件只有Annotations、Collections和DataStore。此外,一些知名App如Cash App开源了Paging分页库,其API与AndroidX下的Paging完全相同,仅包名不同,使用方式一致。
在实际项目中,仅靠社区支持可能无法满足所有业务。为确保使用同一套API,我们可以依赖Kotlin中的expect与actual关键字。expect定义期望实现的方式,actual是具体实现,类似于接口与实现类。例如,要实现打开系统蓝牙的功能,首先在commonMain中使用expect定义接口,然后在androidMain和iOSMain目录下各自实现具体方法,这样调用方不需要关注具体实现。
KMM当前已可用于实际项目,但根据Kotlin的RoadMap,今年将发布正式版本,值得期待。
实践Compose Multiplatform
Compose Multiplatform专注于UI复用,但当前KMM与Compose Multiplatform的版本和插件不统一。要创建Compose Multiplatform项目,可以下载最新版IDEA,但由于iOS还在alpha阶段,IDEA不能直接创建iOS平台项目。因此,使用Kotlin全平台有两种方式:使用IDEA创建项目并添加KMM依赖配置;使用Android Studio创建项目并添加Compose Multiplatform配置;或使用官方提供的模板项目。
这里基于刚刚创建的KMM项目,在基础上添加Compose Multiplatform配置。配置好后,继续实现查询每日一问的功能,将网络数据显示在UI中。通过编写Compose方法来解析网络数据并显示,在Application中调用,代码与Jetpack Compose完全一致。这样Android和iOS的页面效果完全一致,实现了业务逻辑和UI的百分百复用。
Desktop与Web
除了Android和iOS,Desktop与Web端类似,Desktop已经比较成熟,UI可以完全复用Jetpack Compose。Web端早期使用Compose HTML实现,但割裂严重;最新Compose for Web基于Kotlin/Wasm,处于试验阶段,页面可以完全与Jetpack Compose复用,因此不建议学习旧版Compose HTML写法。官方提供了一些Compose Multiplatform模板,但缺少Compose Wasm for Web模板,可以寻找开源模板使用。
与原生UI的互操作性
在使用Jetpack Compose开发Android时,可能需要与XML嵌套使用;在跨平台中,iOS可以通过UIKitView嵌入复杂平台特定小部件,如地图、Web视图等。这些不会阻碍Compose Multiplatform跨平台发展。
开发者该如何选择
当前与Compose跨平台竞争的主要是Flutter,但这样比较对Compose Multiplatform不公平,因为它还很年轻。个人观点是,Flutter存在语言壁垒问题,而KMM和Compose Multiplatform对Android开发者几乎是赠送的。现在可能有两拨人阻碍使用KMM和Compose Multiplatform:没有使用过Jetpack Compose的人和没有使用过Kotlin的人。
对于没有使用过Jetpack Compose的人,可以理解,因为一些组件支持还需要时间;对于没有使用过Kotlin的人,排除特定情况,许多理由如Java也能用、老板不让用等已成为借口。已经在使用Kotlin的开发者,建议学习Jetpack Compose,这是趋势并能扩展跨平台技能。如果想在未来几年内仍从事Android开发,没有理由拒绝。
最后
不破不立,这句话与大家共勉。本次分享到这里结束,期待下次再见。