Compose也能跨平台?Compose Multiplatform是啥?KMM又是什么?
Posted 川峰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Compose也能跨平台?Compose Multiplatform是啥?KMM又是什么?相关的知识,希望对你有一定的参考价值。
现在的跨平台框架真是跟打了鸡血似的,跟生产队的驴一样玩命的更新啊,一会儿功夫就遍地开花,开发者尤其是androiders们还能学得过来吗?
Compose Multiplatform
Compose Multiplatform简单来说就是是JetBrains公司将以下三个库合为一体的统称,又叫Compose-jb:
- compose-android:Jetpack Compose
- compose-desktop:Compose for Desktop
- compose-web: Compose for Web
但是它还是基于KMM之上的,不是单纯的UI框架。
看上去貌似是要一统江湖了,但是仔细一看好像没有ios哎,为啥,很明显,kotlin语言不能直接在iOS平台使用,毕竟不是人家的亲儿子。
借两张图来感受一下:
上图可以看到,iOS端直接空着,白板,不过,相信后面 JetBrains一定会补上iOS端的,就是不知道会以什么样的方式(可是假如你真搞出来了,那叫Swift UI该往哪放)。但是还是希望以后开发者写一套Compose UI就可以适配多个平台,最好是Android代码写完,翻译一下直接可以iOS端用了(按照现在的发展势头完全有可能)。
更快速的了解直接看下面两个链接吧,既然有人总结好了,就没必要再啰嗦了
10个问题带你了解 Compose Multiplatform 1.0
Compose 跨平台的现状
与Flutter比,是否具有可比性?
首先Flutter的目标是移动端跨平台的UI框架,但是JetBrains推出Compose最主要的目的首先是为了在桌面端替换 Swing 和 AWT 等基于 Java 的陈旧的技术栈,只不过Google也趁机想要改变Android原生的UI开发方式,赶上React等现代声明式UI框架的步伐,毕竟类似View.java这样三万多行的屎山实在是改不动了。。。再继续下去要出人命的。。Google的程序猿们估计也开始头大了,但是Jetpack Compose的话,可以独立于Android OS代码发布,因为就是一个gradle中配置的远程依赖,这样就不需要等Android OS更新才能用上新的系统UI组件了,这是第二个目的。
但是如果真的要比,单从编码体验上来说,我感觉Compose UI总体要比Flutter好一点,这里只列出3小点:
- Flutter中要区分有状态和无状态组件,有时要写两个类分别代表有状态和无状态(虽然有更好的社区组件库来解决此问题比如GetX?),而Compose UI就不需要,因为它就是一个kotlin函数,所有的组件都是一个加了Composable注解的函数而已(类比React中的函数式组件)。
- Flutter中更新数据延续了React中的setState()方式的调用,而Compose UI更直接了,连setState()都不用调用了,只要声明时声明成mutableState即可,这点其实更像React中的Hooks。
- 其他的Compose UI比Flutter好的一点就是细节上,在设置组件的样式时,Flutter套的太多层了,比如加个Padding就得套,而Compose就不需要,基本上统一使用修饰符就可以来修改大多数的样式属性,而修饰符Modifer类是可以链式调用的(有点类似装饰者模式)。
真是前人栽树后人乘凉,站在巨人肩膀上就是轻松呀,Compose 把能抄的都抄了过来,不好的地方也给改良了。
那么如果在二者中选择,该用哪个呢?如果是跨平台移动端的话,无疑现阶段最优是Flutter,因为 Compose 压根就不能搞iOS,但是只是现阶段,未来就不一定了,谁知道后面Compose会不会在iOS端发力呢,毕竟大公司都是要脸面的,说不准还会造出来什么奇奇怪怪的东东。从软件界的技术框架发展的趋势来看,后来者一般肯定会带来更优秀的体验(不然干嘛推新的呢,用祖传代码稳一点不好吗)。
KMM又是什么?
这个新名词的全称是 Kotlin Multiplatform Mobile (KMM) 是由 Jetbrains 提供的跨平台移动开发 SDK 。借助 Kotlin 的 跨平台能力,你可以使用一个工程为多个平台编译。它的主要目的是多平台的逻辑代码通过kotlin实现共享,而各自平台用各自的UI框架开发界面,比如Android端使用Compose UI而iOS端使用Swift UI。
来两张官网的图感受一下:
具体是使用 expect / actual 关键字编写平台特定的代码,expect 来声明公共逻辑部分期望的接口方法,actual在具体的平台中实现该方法。
在KMM模式下新建一个工程大概是下面这样:
其中,shared文件就是逻辑共享的部分,存放Android 和 iOS 的公用代码,打开shared里面又是一堆文件夹:
为什么这里又分android ios呢,因为平台Native相关的能力如蓝牙、相机肯定是不同的,代码注定要分开实现,所以要分开来。
- commonMain 下存储为所有平台工作的代码,包括 expect 声明
- androidMain 下存储 Android 的特定代码,包括 actual 实现
- iosMain 下存储 iOS 的特定代码,包括 actual 实现
比如以打印日志为例,打造一个日志SDK
commonMain:
interface IALog
fun v(tag: String, message: String)
expect class ALogImpl(): IALog
androidMain:
import android.util.Log
actual class ALogImpl actual constructor() : IALog
override fun v(tag: String, message: String)
Log.v(tag, message)
iosMain:
import platform.Foundation.NSLog
actual class ALogImpl actual constructor(): IALog
override fun v(tag: String, message: String)
NSLog("[$tag] $message")
到此,已经使用KMM实现了一个简单的日志SDK。
具体的可看下面两个链接简单了解:
Hello World —— 使用 Kotlin 开发跨平台应用
Kotlin/Native KMM项目架构
KMM这种逻辑共享、UI分开的idea还是挺不错的,与Flutter刚好相反,Flutter则是UI共享的。而且国内也已经有团队开始尝试实践KMM的应用了,比如这个携程机票 App KMM 跨端生产实践,但是貌似坑也不少啊,毕竟刚出来的玩意,敢于吃螃蟹的团队,基本上都是有实力的中厂大厂团队,小公司还是算了,大家坑都踩完了再说。
官网指南:Kotlin Multiplatform Mobile
由此看来,如果未来Compose UI能把iOS端拿下,那么使用Compose Multiplatform + KMM就比较香了。
以上是关于Compose也能跨平台?Compose Multiplatform是啥?KMM又是什么?的主要内容,如果未能解决你的问题,请参考以下文章
Docker Compose部署GitLab服务,搭建自己的代码托管平台(图文教程)