前语

说到跨渠道,咱们很简略联想到 ReactNativeFlutter 等业内比较有名的结构,经过在不同渠道复用一套代码,从而进步生产力,一起确保各端逻辑的共同性,他们的确做到了。可是,现在的跨渠道结构都无法做到完美复用,比方双端 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 是利用了 JVMKN 才能完结的针对 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 依靠项。

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile
跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

Shared 模块由三个 SourceSet(源集) 组成:androidMainiosMaincommonMain。源集是一个 Gradle 概念,用于逻辑上组合在一起的许多文件,其中每个组都有自己的依靠项。在 KMM 中,同享模块中的不同源集能够针对不同的渠道。

测验

作为逻辑层跨渠道,咱们首要关心网络恳求、数据解析、数据缓存、多线程等问题。

这儿用一个简略的 demo 来测验一下 KMM,功用是展现天气信息,支撑从网络和数据库缓存获取数据,网络获取成功后对数据进行缓存,然后即可展现缓存数据。这儿除了UI之外,全部用 KMM 完结。

数据界说

KMM 支撑运用 kotlinx.serialization 插件对数据进行序列化和反序列化。

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

用过 Gson 的同学应该很了解,和 Gson 的运用方法简直完全一样,除了导入的包名不同。

网络恳求

在 KMM 中,咱们运用 Ktor 来进行网络恳求。

Ktor 是一个轻松构建联网运用(web 运用、 HTTP 服务、 移动运用以及浏览器运用)的结构。 现代的联网运用需求异步化来供给最佳的用户体会,而 Kotlin 协程为此供给了极端简便的方法。
Ktor 的目标是为联网运用供给端到端的多渠道运用结构,尽管还没有完全完结。现在支撑 JVM 客户端与服务器场景,以及 JavaScript、iOS 与 Android 客户端,而咱们(官方)正努力将服务端支撑引进到原生(native) 环境,并将客户端支撑引进到其他原生渠道。

能够看出,Ktor 便是为了跨渠道而生的。

运用十分简略

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

经过泛型直接反序列化为实体,十分便利。

有些同学或许要问了,JSON 序列化功率太低了,能不能用 ProtoBuf

当然能够,Ktor 现在现已支撑 JSONXMLCBORProtoBuf 序列化格式,只需替换依靠即可,因为 demo 运用的 API 接口运用的是 JSON 格式,因而不再演示 Protobuf 格式的解析方法。

数据缓存

前面提到,Jetpack 的 DataStore 组件现已支撑 KMM,今日咱们来看一下,在 KMM 中如何经过 DB 缓存数据。

这儿咱们要凭借 SQLDelight 这个开源结构,它出自 Square,与 OkHttp 同源。

SQLDelight 从您的 SQL 语句生成类型安全的 Kotlin API。它在编译时验证您的 SchemaStatementsMigrations,并供给如 AutocompleteRefactoringIDE 功用,使编写和保护 SQL 变得简略。

首要,咱们要界说 SQL 文件,用于声明表结构和 CRUD 语句,然后 SQLDelight 插件会帮咱们自动生成代码。

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

为了便利,咱们的数据库中仅界说一个 json 列,不再界说每个特点,数据库存储前先经过 JSON 序列化。这儿仅用于演示 SQLDelight 的运用,请大家不要仿效。

Sync 一下,即可在 build 目录中看到生成的文件,这儿不再一一展现。

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

值得一提的是,因为在不同渠道上 SQL 的完结也不一样,因而需求在 androidMainiosMain 源集中别离创建数据库驱动的完结,不过这些 SQLDelight 现已封装好了,咱们只需求导入即可。

这儿需求用到 KMM 中的一个常用关键字 expect,声明了 expect 的类,即表示需求在各个渠道上别离完结,详见 Connect to platform-specific APIs | Kotlin。

commonMain 中声明 DatabaseDriverFactory

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

androidMainiosMain 别离完结,并增加 actual 关键字

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

最后,创建 Database 类来封装对数据库的操作

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

至此,咱们现已能够运用 KMM 完结天气数据的网络获取和数据库缓存。

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

UI 的代码这儿不再展现,咱们来看一下终究效果

小结

从可用性方面来说,在 KMM 上能够运用开源结构进行网络恳求、数据缓存等,常见的数据格式都现已支撑,并且这些开源库都现已供给安稳版别;从易用性方面来说,作为 Androider,简直是0本钱上手,且开源结构的运用都十分简略,甚至比 Android 原生的开源结构(OkHttpRoom 等)运用更简略,iOSer 或许需求必定的学习本钱。综上,我认为 KMM 在功用上现已能够满意根底的逻辑层跨渠道诉求,在运用上也十分简略。

最后附上 demo 源码

Features

易上手

因为运用 Kotlin 言语,因而 Android 同学不需求学习本钱,iOS 同学需求了解 Kotlin 的语法,即便如此,作为一门现代言语,Kotlin 仍是十分简略上手的!

功用

作为跨渠道结构,功用是一个关键指标。

在 Android 上,Kotlin 代码会被编译成 JVM 字节码,即 class 文件,终究打包到 dex 中,因而能够认为和原生功用共同。

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

在 iOS 上,Kotlin/Native 编译器会将 Kotlin 代码转化为所谓的 LLVM IR,这与 Swift 编译器的方式相同,终究,会运用和 Swift 相同的东西链,将这个 LLVM IR 会被转化为原生可执行的二进制文件。

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

官方的流程图

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

因为运用原生相同的编译方式,KMM 比较其他跨渠道结构,在功用上更有优势。运用依据 JetBrains 官方的描绘,KMM 现在现已十分挨近原生运用的功用,甚至现已能够和原生相等,并且,他们还没有运用一切的优化手法,未来, KMM 的功用将有进一步提高。

或许有些同学会问,KMMRust 功用比照方何?

原生互操作

不论是在 React Native 仍是 Flutter 上,JavaScript/Dart 与原生代码彼此操作都是十分费事的,需求经过“桥接通讯”来完结。

因为 KMM 能够编译为和原生库一样的方式,因而,能够和原生开发言语直接彼此调用。 一起,KMM 代码也能够很简略的打包为 Library,供给给其他 APP 运用。

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

轻量

因为 KMM 终究的编译产物是根据双端标准组件输出,因而无需内置多套引擎 (runtime),包体积增量更少,一起 iOS 端审阅被拒危险也比较小。

UI 跨渠道*

你认为 KMM 会止步于逻辑层跨渠道吗?

NO,依据官方规划,KMM 的 UI 跨渠道功用现已在 KMM 的方案之中,并附带了一张效果图

跨平台还能怎么玩?试试 Kotlin Multiplatform Mobile

重视 Compose 的同学应该知道,Compose Multiplatform UI 跨渠道结构在 2021 年底就现已发布了安稳版,支撑 Android、Web 和桌面的 UI 跨渠道,只是迟迟没有支撑 iOS,现在只需求处理在 iOS 上的复用,尽管现在还没有任何阶段性效果,可是也值得等待!

有些同学或许对 Jetpack ComposeCompose 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 上的协程存在功用问题,官方仍然在优化中。