简介
Kotlin Multiplatform Mobile,缩写为KMM,记住这个缩写,今后遇到它,知道是在说什么
KMM目前处于alpha阶段,预计在2022年春季发布beta版本。就是今年春天,还剩几天时间了,猜一下会不会延期?
截止到今天(2022/4/7),仍是alpha版本,也就是beta版本延期了。
KMM用于简化跨平台应用开发。使用KMM可以用kotlin写代码,并可以在android和iOS之间共享这些代码,也可以使用kotlin写平台特有的代码
跨平台的原理
使用kotlin编写,之后编译出目标平台代码
借助Kotlin Multiplatform,可以让用Kotlin写的代码可以在所有平台上运行
Kotlin/Native是什么
- Kotlin/Native是一种把Kotlin代码编译为native二进制并且无需虚拟机就能运行的技术
包大小
Android 平台以 aar 的形式集成,许多依赖的 Kotlin 基础库,例如 kotlinx.coroutines 以及 kotlinx.serialization 等等都没有打进这个 aar 里,再加上编译产物又是字节码,总 size 增长只有 0.03 MB。但是 iOS 有所不同,编译产物是二进制码,再加上整个 Kotlin/Native 的基础库、Runtime 等等通通打进了这个 Framework,总 size 增长为 1.5 MB,当然后续再持续集成业务代码的话,增长幅度不会再这么惊人
KMM对比Flutter
体积
-
使用 Flutter 需要在 App 包内部增加两个引擎:
- 一个是 Flutter 的渲染引擎,该引擎使用 C/C++ 开发,直接调用 OpenGL/Skia 的 API 进行绘制,从而摆脱 iOS 的 UIKit 以及 Android 的 View 组件直接渲染成需要的样式,从保证样式高度统一
- 一个是 Dart 语言的 Runtime,用于解析并运行 Dart 语言编译的 Bundle
这两者减小了开发者的适配成本,但增大了 APP 的包体积(其他类似的跨平台框架,如:React Native 等,也会内置 JavaScript Core 或 V8 引擎)
-
KMM 针对不同平台生成不同的二进制依赖包,根本上还是调用了 Android、iOS 的原生 API,并不会内置引擎这类文件,对 App 的体积影响相对较小,同时也保证了性能
技术栈
- Flutter 使用 Dart 开发,无论是 Web 开发者,还是原生 App 开发者,都需要抽时间去学习一门新的语言,理解新的开发模式,虽然 Dart 与 JavaScript、Java 有着类似之处,且开发形式和 React 相近,但仍有一定学习门槛
- Kotlin 已经成为 Google 官方主推的 Android 开发语言,且由于Kotlin 与 Java 交互非常方便,目前很多 Android 开发者已经完全切换到 Kotlin 来进行 App 开发,很多与平台无关的工具类、算法、数据模型可以直接利用 KMM 实现跨平台,与 Flutter 相比,至少 Android 开发者的门槛要求较低
风险点
- 众所周知,App Store 对 App 的审核一直都是极为严格的,JSPatch、React Native 等框架的使用都有过审核被拒的情况,从某种角度来看,Flutter 与 Swift UI 在一定程度上目标相似,且绕开 iOS SDK 的 UIKit,Apple 虽没有明确对 Flutter 表态,但按照 Apple 的风格,Flutter 在未来仍存在一定的被拒风险
- KMM 会将 Kotlin 代码编译为标准的 Apple Framework,在不引入其他第三方库的情况下,不存在调用高风险 API 的情况,故对 App Store 审核的影响较小,风险较低
适用场景
- 由于 Flutter 采用类似 3D 游戏的渲染理念,统一了界面渲染引擎,利用 Dart 可以高度保证双端样式和交互逻辑一致,且几乎不存在界面适配问题,完全抹平了 TextView 和 UILabel 这类控件之间的差异,所以 Flutter 适合于界面构建
- 而 KMM 并不适合 UI,双端的组件,生命周期、API 差异都比较大,KMM 在技术上可以实现功能,但相当于写了两份代码,失去了意义;KMM适合写逻辑的代码。
看一个例子
工程结构
image.png- androidApp:Android工程代码
- iosApp:iOS工程代码
- shared:Kotlin编写的跨平台代码
android和iOS设置依赖后,可以直接引用shared工程内的"kotlin"代码
shared目录
commonMain
// expect关键字:申明是平台差异化代码
expect class Platform() {
val platform: String
}
class Greeting {
fun greeting(): String {
return "Hello, ${Platform().platform}!"
}
}
androidMain
// actual:是平台差异化代码的实现
actual class Platform actual constructor() {
actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}"
}
iOSMain
import platform.UIKit.UIDevice
// actual:是平台差异化代码的实现
actual class Platform actual constructor() {
actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}
androidApp目录
fun greet(): String {
return Greeting().greeting()
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val tv: TextView = findViewById(R.id.text_view)
tv.text = greet()
}
}
运行
Android iOS我们哪些场景可以使用KMM?
- 数据埋点
- 网络请求
- 加解密
- 与Compose配合,完整实现跨平台开发(Compose当前只支持Android平台,但是它是有扩展至其他平台的能力)
参考文章
https://kotlinlang.org/docs/multiplatform-mobile-getting-started.html
https://blog.jetbrains.com/zh-hans/kotlin/2021/05/whats-new-in-kmm-since-going-alpha/
https://coderyuan.com/2021/05/26/KMM-1/
https://cloud.tencent.com/developer/article/1889664
https://mp.weixin.qq.com/s/e3k5JcxG1FvGlNkOyjNIFw
网友评论