作者简介
陈琦,携程机票研发部无线研发总监,负责携程App机票业务的技术研发和管理工作。
从2017年9月到2019年5月,经过一年半的努力,携程机票App团队完成 90% 从 Native 到 Ctrip React Native (CRN) 的技术栈转型。
2019年初,我们开始思考下一步规划。
除了继续做深 React Native 技术,更快更稳定的迭代交付机票业务需求,优化用户体验,我们需要从具体业务逻辑实现层次抽离出来,从一个完整的应用程序架构设计和实现的角度,寻找跨平台技术的未来方向。
React Native 和 Flutter 这类大前端技术方案已经可以很好的支撑用户界面和组件,业务逻辑需求功能的实现,但是单线程动态脚本语言在以下领域仍显不足。
灵活调用强大的平台/厂商 API (AI, AR, mult-core GPU, ...)
高性能计算
多线程处理
后台任务
低功耗
我们希望能够找到一种可靠的跨平台,原生,或能够与原生 API 进行灵活自由双向互操作的技术方案。经过一段时间的针对 Kotlin 及相关开源社区的调研,观察,实践,Kotlin Multiplatform 技术在这方面展现出了良好的发展潜力。
一、Native multiplatform
传统主流的跨平台原生方案是 C/C++,目前依然是最被广泛使用的。 React Native 和 Flutter 的底层实现也是如此。
Kotlin Multiplatform 的跨平台迁移如下图。
二、Kotlin Native
了解 Kotlin Multiplatform 需要先从 Kotlin Native 入手。相比 Kotlin/JVM,Kotlin Native 使用 Kotlin 语言编译器,配合 LLVM backend,将 Kotlin 代码编译为平台原生二进制文件,不依赖虚拟机或运行时环境。当前 LLVM 版本 6.0.1 。官方正在将编译方案从 LLVM 的backend 转移到 frontend (clang) 。
目前已支持的平台:
iOS 9.0+ (arm32, arm64, x86_64 模拟器)
macOS (x86_64)
Android (arm32, arm64) ,编译生成 Linux SO 文件
Windows (mingw x86_64, x86)
Linux (x86_64, arm32, MIPS, MIPS little endian, Raspberry Pi)
WebAssembly (wasm32)
三、Kotlin Native 与 C 双向互操作
3.1 cinterop
Kotlin Native 官方附带工具,用于快速生成Kotlin与平台C库互相调用操作所需的内容。
首先创建一个.def文件,描述需要包含在语言绑定的内容。
然后使用 cinterop 分析C头文件,映射生成 Kotlin 语言的类型,函数和常量,完成Kotlin绑定。
最后通过LLVM编译器链接生成最终的可执行文件 *.kexe 或库文件 *.klib。
kexe 是平台相关的可执行程序文件格式。
klib 是平台相关的库文件格式,类似 JAR 的ZIP格式,细节详见官网文档:https://kotlinlang.org/docs/reference/native/libraries.html#the-library-format
解压后的文件夹结构如下:
- foo/
- targets/
- $platform/
- kotlin/
- Kotlin compiled to LLVM bitcode.
- native/
- Bitcode files of additional native objects.
- $another_platform/
- There can be several platform specific kotlin and native pairs.
- linkdata/
- A set of ProtoBuf files with serialized linkage metadata.
- resources/
- General resources such as images. (Not used yet).
- manifest - A file in *java property* format describing the library.
3.2 平台库
大多数情况下,我们并不需要使用 cinterop 手动生成所有所需的C库绑定。
Kotlin Native SDK已经提供了大部分平台的原生库绑定。例如:
Linux POSIX
Windows Win32
macOS/iOS Apple Framework, POSIX
以及各平台的常用热门库,OpenGL, zlib 等
Kotlin Native 在本机开发时默认下载到 ~/.konan/ 文件夹,例如 ~/.konan/kotlin-native-macos-1.2.1/, 平台库文件位于~/.konan/kotlin-native-macos-1.2.1/klib/platform/,已包含以下内容,可见大部分平台SDK都已预处理完成。
Android Native Arm32
├── android
├── android_arm32.tree.txt
├── builtin
├── egl
├── gles
├── gles2
├── gles3
├── glesCommon
├── linux
├── media
├── omxal
├── posix
├── sles
└── zlib
13 directories, 1 file
iOS Arm64
├── ARKit
├── AVFoundation
├── AVKit
├── Accelerate
├── Accounts
├── AdSupport
├── AddressBook
├── AddressBookUI
├── AssetsLibrary
├── AudioToolbox
├── AuthenticationServices
├── BusinessChat
├── CFNetwork
├── CallKit
├── CarPlay
├── ClassKit
├── CloudKit
├── CommonCrypto
├── Contacts
├── ContactsUI
├── CoreAudio
├── CoreAudioKit
├── CoreBluetooth
├── CoreData
├── CoreFoundation
├── CoreGraphics
├── CoreImage
├── CoreLocation
├── CoreMIDI
├── CoreML
├── CoreMedia
├── CoreMotion
├── CoreNFC
├── CoreServices
├── CoreSpotlight
├── CoreTelephony
├── CoreText
├── CoreVideo
├── DeviceCheck
├── EAGL
├── EventKit
├── EventKitUI
├── ExternalAccessory
├── FileProvider
├── FileProviderUI
├── Foundation
├── GLKit
├── GSS
├── GameController
├── GameKit
├── GameplayKit
├── HealthKit
├── HealthKitUI
├── HomeKit
├── IOSurface
├── IdentityLookup
├── IdentityLookupUI
├── ImageIO
├── Intents
├── IntentsUI
├── LocalAuthentication
├── MapKit
├── MediaAccessibility
├── MediaPlayer
├── MediaToolbo