前言
在去年 DevFest 的 Compose Camp 活动上,fundroid 与朱江两位讲师带着大家使用 Compose 实现了灵动岛效果
但是灵动岛毕竟是 iOS 上的特性,正好今年 KotlinConf 上宣布了 Compose-iOS 已经 alpha 了,那么如果我们将已经用 Compose 实现的灵动岛效果,移植到 iOS 上又会怎么样呢?
想想多是一件美事啊,说干就干,看看把代码从 Jetpack Compose 迁移到 Compose Multiplatform 中到底要做什么工作,要付出什么成本
效果展示
首先看下效果,可以看到,基本实现了灵动岛切换的动画效果,与在 Android 上的效果也基本一致
实现步骤
环境配置
要使用 Compose MultiPlatform 开发,需要以下环境
- XCode
- Android Studio
- Kotlin Multiplatform Mobile 插件
- Cocoapods 依赖管理器
其实跟 Kotlin Multiplatform 所需要的环境一致,其中最麻烦的可能是 Cocoapods 的安装,可以查看 KMM 安装 Cocoapods 的文档:Set up an environment to work with CocoaPods
此外,你也可以通过kdoctor
命令来检查环境配置否正确
brew install kdoctor // 安装 kdoctor
kdoctor // 检查
如果所有环境都配置正确,你会看到以下输出
Environment diagnose (to see all details, use -v option):
[✓] Operation System
[✓] Java
[✓] Android Studio
[✓] Xcode
[✓] Cocoapods
Conclusion:
✓ Your system is ready for Kotlin Multiplatform Mobile development!
创建项目
Compose Multiplatform 项目其实就是在 KMM 项目中加入一些 Compose 的内容,还是有不少模板代码的,我们可以直接使用 JetBrains 提供的项目模板生成项目:compose-multiplatform-ios-android-template
如图所示,其实就是一个 KMM 工程的结构,android 项目的入口是 androidApp,iOS 项目的入口是 iosApp,共享代码放在 shared 模块
在 shared 模块中,各个平台共享代码放在 commonMain 目录中,而各个平台的定制代码则放在 androidMain 与 iosMain 中
在这里主要的不同在于,android 平台直接返回了一个 Composable 函数,供 android 层调用,而 iOS 平台则返回了一个 UIViewController
代码移植
在项目创建完成后,接下来就是代码移植的工作了。移植过程可以说是非常简单,基本上不用做任何改动,Jetpack Compose 项目就可以迁移成 Compose Multiplatform 项目
在我迁移过程中碰到的唯一不同在于资源文件的处理,如下所示,R 文件引用方式需要修改成字符串方式引用
// Jetpack Compose
Image(
painterResource(R.drawable.icon_cover),
"music cover",
Modifier
.size(animationData.musicImageSize)
.clip(RoundedCornerShape(animationData.musicImageCorner))
)
// Compose Multiplatform
Image(
painterResource("icon_cover.xml"),
"music cover",
Modifier
.size(animationData.musicImageSize)
.clip(RoundedCornerShape(animationData.musicImageCorner))
)
除此之外,两者的状态管理,布局,动画等 api 是完全一致的,可以直接复用代码
经过以上步骤,迁移就完成了,直接运行 androidApp 与 iosApp 就可以得到文章开始展示的效果了
正在处理中的问题
当然,现在 Compose Multiplatform 还处在 alpha 阶段,并不是说已经可以用于生产了,还有不少问题正在处理中
待支持的功能
图片来源:Compose Multiplatform on iOS by: Sebastian Aigner and Nikita Lipsky
可以看出,Compose Multiplatform 还是有不少细节问题要处理的
性能问题
我们打开 XCode 的 instruments 然后运行 app,就可以得到运行的 trace 文件,统计出运行次数较多或者比较耗时的方法
可以看出,耗时方法有相当一部分是 GC 相关的,当 GC 暂停发生时,会冻结所有对象,自然也会影响 UI 的渲染,导致卡顿
好消息是 Kotlin 正在优化 GC,期望将 GC 暂停控制在 1 到 2 ms 之内
总结
可以看出将 Jetpack Compose 版的灵动岛迁移到 Compose Multiplatform 的成本是非常低的,最耗时的部分可能是配环境的部分,两者的 API 基本上是一致的,因此代码可以无缝复用
Compose 跨平台补全了 Kotlin 跨平台只支持共享逻辑不支持共享 UI 的短板,降低了 Kotlin 跨平台的开发成本,总得来说,未来可期,希望 Jetbrains 能早日推出正式版
示例代码
本文所有代码可见:github.com/RicardoJian…
参考资料
Compose Multiplatform on iOS by: Sebastian Aigner and Nikita Lipsky