前语
说到跨渠道,咱们很简略联想到 ReactNative
、Flutter
等业内比较有名的结构,经过在不同渠道复用一套代码,从而进步生产力,一起确保各端逻辑的共同性,他们的确做到了。可是,现在的跨渠道结构都无法做到完美复用,比方双端 UI 上的差异,导致还需求写许多适配代码,还有一个比较核心的问题,无法比美原生功用。
简介
那 Kotlin Multiplatform Mobile(以下简称 KMM)又是什么呢,先看下官方的介绍
Kotlin Multiplatform Mobile 是一个用于 iOS 和 Android 运用开发的 SDK,允许您为网络、数据存储和分析以及 Android 和 iOS 运用的其他逻辑保护一个同享代码库。
不同于 Flutter
这样的完整跨渠道结构,KMM 不包含渲染引擎,不支撑 UI 层的代码同享,而像网络恳求、数据解析和存储,以及一些 UI 无关的事务逻辑,都能够运用 KMM 同享代码。
有些同学或许也听说过 KMP、KN等,它们和 KMM 又是什么关系?
简略来说:
- KMP 一般指的便是 `Kotlin Mutiplatform`,能够认为是 Kotlin 跨渠道的全集,包含 KMM 移动端跨渠道和 `Kotlin JS` Web 跨渠道
- KN 一般指的是 `Kotlin Native`,KN 是将 Kotlin 编译为 Native 二进制文件的技术,甚至能够在没有虚拟机的情况下运行,例如 KMM 上的 iOS 便是运用了 KN 的才能
- KMM 是利用了 JVM 和 KN 才能完结的针对 Android 和 iOS 渠道的 Kotlin 结构:Android(`Kotlin/JVM`)和 iOS(`Kotlin/Naitve`)
了解 Android 开发的同学应该有所了解,KMM 并不是什么新鲜玩意,它在2020年就发布了第一个版别,根据 Kotlin 1.4 版别,不过因为一直处于试验阶段,因而运用和了解的人比较少。
那么为什么今日又提起它了,原因是它在2022年10月发布了 Beta 版别,一起 Android 官方宣布 Jetpack 开始要支撑 KMM 了,现在 Collections 和 DataStore 现已能够经过依靠 -dev01
版别在多渠道上运用,也就意味着 KMM 的社区支撑有了官方确保,别的依据 JetBrains
的官方信息,如无意外,KMM 的安稳版会在 2023 年发布,因而间隔 KMM 能够投入生产现已很挨近了!
结构
在开始之前,咱们先来了解一下 KMM 的开发方式。
每个 KMM 项目都包含三个模块:
-
Shared
是一个 Kotlin 模块,其中包含 Android 和 iOS 运用程序通用的逻辑,是在渠道之间同享的代码。它运用 Gradle 作为构建系统,帮助您自动执行构建进程。同享模块内置到 Android 库和 iOS 结构中。 -
AndroidApp
是一个内置到 Android 运用程序中的 Kotlin 模块。它运用 Gradle 作为构建系统,AndroidApp
模块依靠于同享模块,并将同享模块用作惯例的 Android 库。 -
iOSApp
是一个内置到 iOS 运用程序中的 Xcode 项目。它依靠于并运用同享模块作为 iOS 结构。同享模块能够用作惯例结构或 CocoaPods 依靠项。
Shared
模块由三个 SourceSet(源集) 组成:androidMain
、iosMain
和 commonMain
。源集是一个 Gradle 概念,用于逻辑上组合在一起的许多文件,其中每个组都有自己的依靠项。在 KMM 中,同享模块中的不同源集能够针对不同的渠道。
测验
作为逻辑层跨渠道,咱们首要关心网络恳求、数据解析、数据缓存、多线程等问题。
这儿用一个简略的 demo 来测验一下 KMM,功用是展现天气信息,支撑从网络和数据库缓存获取数据,网络获取成功后对数据进行缓存,然后即可展现缓存数据。这儿除了UI之外,全部用 KMM 完结。
数据界说
KMM 支撑运用 kotlinx.serialization
插件对数据进行序列化和反序列化。
用过 Gson 的同学应该很了解,和 Gson 的运用方法简直完全一样,除了导入的包名不同。
网络恳求
在 KMM 中,咱们运用 Ktor
来进行网络恳求。
Ktor 是一个轻松构建联网运用(web 运用、 HTTP 服务、 移动运用以及浏览器运用)的结构。 现代的联网运用需求异步化来供给最佳的用户体会,而 Kotlin 协程为此供给了极端简便的方法。
Ktor 的目标是为联网运用供给端到端的多渠道运用结构,尽管还没有完全完结。现在支撑 JVM 客户端与服务器场景,以及 JavaScript、iOS 与 Android 客户端,而咱们(官方)正努力将服务端支撑引进到原生(native) 环境,并将客户端支撑引进到其他原生渠道。
能够看出,Ktor
便是为了跨渠道而生的。
运用十分简略
经过泛型直接反序列化为实体,十分便利。
有些同学或许要问了,JSON 序列化功率太低了,能不能用 ProtoBuf
?
当然能够,Ktor
现在现已支撑 JSON、XML、CBOR 和 ProtoBuf 序列化格式,只需替换依靠即可,因为 demo 运用的 API 接口运用的是 JSON 格式,因而不再演示 Protobuf
格式的解析方法。
数据缓存
前面提到,Jetpack 的 DataStore
组件现已支撑 KMM,今日咱们来看一下,在 KMM 中如何经过 DB 缓存数据。
这儿咱们要凭借 SQLDelight
这个开源结构,它出自 Square
,与 OkHttp 同源。
SQLDelight 从您的 SQL 语句生成类型安全的 Kotlin API。它在编译时验证您的 Schema、Statements 和 Migrations,并供给如 Autocomplete 和 Refactoring 等 IDE 功用,使编写和保护 SQL 变得简略。
首要,咱们要界说 SQL 文件,用于声明表结构和 CRUD 语句,然后 SQLDelight
插件会帮咱们自动生成代码。
为了便利,咱们的数据库中仅界说一个 json 列,不再界说每个特点,数据库存储前先经过 JSON 序列化。这儿仅用于演示 SQLDelight
的运用,请大家不要仿效。
Sync 一下,即可在 build 目录中看到生成的文件,这儿不再一一展现。
值得一提的是,因为在不同渠道上 SQL 的完结也不一样,因而需求在 androidMain
和 iosMain
源集中别离创建数据库驱动的完结,不过这些 SQLDelight
现已封装好了,咱们只需求导入即可。
这儿需求用到 KMM 中的一个常用关键字 expect
,声明了 expect
的类,即表示需求在各个渠道上别离完结,详见 Connect to platform-specific APIs | Kotlin。
commonMain
中声明 DatabaseDriverFactory
androidMain
和 iosMain
别离完结,并增加 actual
关键字
最后,创建 Database
类来封装对数据库的操作
至此,咱们现已能够运用 KMM 完结天气数据的网络获取和数据库缓存。
UI 的代码这儿不再展现,咱们来看一下终究效果
小结
从可用性方面来说,在 KMM 上能够运用开源结构进行网络恳求、数据缓存等,常见的数据格式都现已支撑,并且这些开源库都现已供给安稳版别;从易用性方面来说,作为 Androider,简直是0本钱上手,且开源结构的运用都十分简略,甚至比 Android 原生的开源结构(OkHttp
、Room
等)运用更简略,iOSer 或许需求必定的学习本钱。综上,我认为 KMM 在功用上现已能够满意根底的逻辑层跨渠道诉求,在运用上也十分简略。
最后附上 demo 源码。
Features
易上手
因为运用 Kotlin 言语,因而 Android 同学不需求学习本钱,iOS 同学需求了解 Kotlin 的语法,即便如此,作为一门现代言语,Kotlin 仍是十分简略上手的!
功用
作为跨渠道结构,功用是一个关键指标。
在 Android 上,Kotlin 代码会被编译成 JVM 字节码,即 class 文件,终究打包到 dex 中,因而能够认为和原生功用共同。
在 iOS 上,Kotlin/Native
编译器会将 Kotlin 代码转化为所谓的 LLVM IR
,这与 Swift
编译器的方式相同,终究,会运用和 Swift
相同的东西链,将这个 LLVM IR
会被转化为原生可执行的二进制文件。
官方的流程图
因为运用原生相同的编译方式,KMM 比较其他跨渠道结构,在功用上更有优势。运用依据 JetBrains
官方的描绘,KMM 现在现已十分挨近原生运用的功用,甚至现已能够和原生相等,并且,他们还没有运用一切的优化手法,未来, KMM 的功用将有进一步提高。
或许有些同学会问,KMM 与 Rust 功用比照方何?
原生互操作
不论是在 React Native
仍是 Flutter
上,JavaScript
/Dart
与原生代码彼此操作都是十分费事的,需求经过“桥接通讯”来完结。
因为 KMM 能够编译为和原生库一样的方式,因而,能够和原生开发言语直接彼此调用。 一起,KMM 代码也能够很简略的打包为 Library,供给给其他 APP 运用。
轻量
因为 KMM 终究的编译产物是根据双端标准组件输出,因而无需内置多套引擎 (runtime),包体积增量更少,一起 iOS 端审阅被拒危险也比较小。
UI 跨渠道*
你认为 KMM 会止步于逻辑层跨渠道吗?
NO,依据官方规划,KMM 的 UI 跨渠道功用现已在 KMM 的方案之中,并附带了一张效果图
重视 Compose 的同学应该知道,Compose Multiplatform
UI 跨渠道结构在 2021 年底就现已发布了安稳版,支撑 Android、Web 和桌面的 UI 跨渠道,只是迟迟没有支撑 iOS,现在只需求处理在 iOS 上的复用,尽管现在还没有任何阶段性效果,可是也值得等待!
有些同学或许对 Jetpack Compose
和 Compose Multiplatform
还不太了解,这儿简略介绍下
`Jetpack Compose` 是 Google 针对 Android 推出的新一代声明式 UI 东西包,完全根据 Kotlin 打造,天然具有了跨渠道的运用根底。
JetBrains 以 `Jetpack Compose`(后文简称 `compose-android`)为根底,相继发布了 `compose-desktop` 和 `compose-web` ,使 Compose 能够运行在更多不同渠道。
小结
KMM 运用 Kotlin 言语,对 Android 开发者十分友爱。
在功用方面,因为现在运用 KMM 的产品比较少,因而没有找到真实可信的测试数据,咱们权且信任官方介绍。
依据官方的描绘,KMM 在 iOS 和 Android 上别离都会转为和原生共同的中间产物,因而挨近原生功用,并且 KMM 团队后续还会侧重优化 KMM 的功用,未来可期!
别的,能够和原生言语直接彼此调用也是一大优势,一起根据 Kotlin 到原生的转化才能,KMM UI 跨渠道才能相同值得等待!
缺乏
并发
在 Android 上,咱们能够很便利的运用根据 JVM 线程池的 Kotlin Coroutines 来进行并发操作,但因为 Kotlin/Native 和 JVM 的内存模型差异,导致 iOS 上的协程只能运用单一后台线程,官方有一篇博客专门对 Kotlin/Native 的内存管理做了介绍 。
对此,Kotlin 团队重新规划了 Kotlin/Native 上的内存管理器,并在 Kotlin 1.7.20
版别默认启用
新的 Kotlin/Native 自动内存管理器解除了线程之间对象同享的现有约束,并供给完全无泄漏的并发编程原语,这些原语是安全的,不需求开发人员的任何特殊管理或注释。
看起来 Kotlin/Native 现已处理了并发的问题,不过是否彻底处理还需求线上产品来验证。
总结
本文首要介绍了 KMM 是什么,经过一个 demo 演示 KMM 跨渠道复用代码的才能,包含网络恳求、解析和数据缓存等,现在开源社区还不行完善,仅能满意根底功用,不过有 Android Jetpack 的参加,信任开源组件会越来越丰富。
依据 KMM 的编译方式和官方介绍,能够看出 KMM 在功用上挨近原生,一起 KMM 支撑和原生代码互操作,KMM UI 跨渠道在官方方案之中,值得等待。可是现在 KMM 在并发操作上还存在缺乏,在 iOS 上的协程存在功用问题,官方仍然在优化中。