Kotlin Multiplatform 实战记 | QCon

2021 年 11 月 13 日 InfoQ
作者 | 曹立成

10 月 21 日我在上海举办的 QCon 全球软件开发大会上分享了 Kotlin Multiplatform 相关的内容,这里记录成文章,分享给你。

1 为什么选择 Kotlin 跨平台?

我先介绍一下我们团队的情况,交代清楚我们技术选型的背景。

我们是阿里巴巴 1688 无线团队,主要负责阿里巴巴客户端、1688 工业品、商家版和采源宝四个 App,是 Android & iOS 混合团队,双端的同学都有。主要负责基础业务、搜索、首页、用增相关等内容,会经常遇到多个 App 部分业务需要复用的情况。在日常开发中,会遇到以下几个问题:

  • 基础模块逻辑相对复杂,多端研发成本高

  • 双端逻辑代码膨胀,无法保证完全一致,问题排查难

  • 逻辑代码穿插在各个模块中,现有跨端复用方案迁移成本高

这些问题可能很多存量 App 都会遇到,随着不断迭代,很多逻辑写着写着双端就出现不一样的细节了,出了问题不好查,迭代维护成本又高,如果再出现人员变动,那一部分代码就会变成「祖传代码」。

为了解决这些问题,我们希望寻找一种方法,可以将逻辑收拢,提升研发效能,降低维护成本。从技术栈的角度出发,我们对比了 Flutter、Kotlin Multiplatform、React Native 三种方案:

我们的诉求是,能够收拢逻辑层面的东西,UI 并不重要,因为我们已经有统一协议渲染框架。而且我们需要更好的性能,对原生能力的融合(不要桥),以及较低的上手学习成本和更轻量化的方案。所以我们选择了 Kotlin Multiplatform。在下文中,我会多次提到 KMM 这个简称,这里先简单讲一下 KMM 是什么:

  • 基于 KMP(Kotlin Multiplatform)派生,全称 Kotlin Multiplatform Mobile。它不是一个框架,是一种研发范式,通过代码管理与插件,降低 Kotlin 跨 Mobile 端上手门槛

  • 更贴合 Android & iOS 平台。Android 平台产物 aar,iOS 平台使用 Kotlin Native 编译,产物 framework

  • 与平台无关的 common 逻辑可以跨更多的平台,如 Mac、Linux、Windows、Web 等

2 Kotlin 是如何实现跨平台的?(技术解析)
代码工程结构

对于 Kotlin Multiplatform 来说,代码工程结构会和其他的工程不太一样。官方给出的基础结构是一个 commonMain 的代码包,其他平台的代码包依赖它(jvmMain、jsMain 等)。对于 KMM 工程来说,通过 Android Studio KMM 插件生成的结构是这样的:

如何扩展原生能力

先举一个最简单的例子,实现一个双端的 Log 工具。在 commonMain 里定义好 expect fun,然后分别在 iosMain 和 androidMain 中实现 actual fun。

1 + 1 = 2 的例子举完了,在真正的应用开发中,调用 Android 能力是非常简单的,和普通 Android 开发没有区别,只要通过 gradle 引入需要的库,就可以调用里面的代码了。iOS 则是通过 cinterop 这个能力生成 Kotlin 识别的三方库头文件实现能力调用的。

cinterop 是 Kotlin Native 支持的能力,KMM 工程的编译使用了 gradle 工具链,其中对 iOS 来说,我们使用了 Kotlin CocoaPods 插件。引入一个三方库,首先通过 pod 脚本写好库和版本,接着执行 gradle sync,其中会执行两个关键的 task,第一个是 podGen,它会把我们需要依赖的库通过 pod 拉到本地,生成一个壳工程,然后会执行对应库的 cinterop task,执行成功以后会生成上图里的 klib 文件,里面包含了导出的头文件函数(knm 文件),最后代码里 import 进来就可以直接使用了。

内存管理机制
  • Android:现代垃圾回收算法

  • iOS(Kotlin Native):基于引用计数的垃圾回收算法,额外增加了对环的处理

多线程实践
  • 不可变状态才允许多线程访问(Kotlin Native 中不可变不只是 val ,必须是 frozen 状态)

  • 使用协程库

  • 使用 @ThreadLocal 或 @SharedImmutable

  • 封装平台特性的线程方法(线程池、Handler、GCD)

  • 使用原子类(Atomic)

3 Kotlin Multiplatform 在阿里巴巴的实践
1688

日志

我们在日志建设上使用了 Kotlin 收拢双端逻辑。对于偏中间件的开发来说很好理解,Kotlin 调用双端基础能力,提供对上的 API 即可。代码示例如下:

上层入口提供了 log 的 API,调用的就是 Kotlin 代码中 LogKit 里的 log 方法。对于 log 相关的配置和策略,通过 LogConfig.kt 封装实现。最终上报也是使用了原生的上报通道,对接了原生已有的能力,比如 TLog ,这是我们的个案日志上报系统,expect 定义好 fun,双端各自实现。整个日志模块中 Kotlin 部分,起到一个承上启下的作用。

搜索筛选

搜索筛选是个业务场景,1688 APP 首页就可以直接跳转到搜索,是一个非常大的流量入口。搜索逻辑比较复杂,有不同场景的搜索、不同品类的搜索、下拉的筛选项、侧边栏的筛选项等。在开发维护搜索逻辑的时候,我们遇到过好几次由于双端逻辑不一致,出现问题很难排查的情况。为了追求双端逻辑强一致,我们把搜索筛选业务的请求策略、场景管理、筛选模型、埋点策略封装在了 Kotlin 中。

FilterManager 是最核心的入口,用户点击筛选项就会走到这里。通过筛选模型和场景模型联合处理,最终拿到请求参数给 UI 层,再通过我们已有的统一协议渲染框架进行渲染。从收益上看,我们的人力投入减少了大概 30%,稳定性持平,逻辑强一致,维护成本降低,排查问题成本也降低。

饿了么商家端

饿了么商家端也深度使用了 Kotlin 收拢双端逻辑,还使用了 Redux 管理数据流。这里就不展开细讲了,详细内容可以查看 PPT,会在文末给出链接。

4 应用场景

总结一下,Kotlin Multiplatform 比较适合以下场景:

  • 没有 UI 的复杂逻辑场景

  • 基于 MVP 设计的复杂业务中 M 和 P 层

不太适合以下场景:

  • 涉及 UI 的场景

  • 动态化较多的场景

5 研发模式

根据我们的实践经验,我给大家推荐三种研发模式:

对于基础库开发来说,其实比较简单,Kotlin 把双端逻辑收拢,提供对上 API 调用双端能力即可。对于常规业务开发来说,我更推荐 MVP 设计法则,把 M 和 P 层收拢在 Kotlin 中。如果有多端业务开发的场景(常见于 B 端业务),逻辑层可以用 Kotlin 跨更多的平台,饿了么商家端和美团商家端就有在这个场景下使用。

6 最后

目前在用 Kotlin Multiplatform 进行开发的国内互联网公司有:阿里巴巴、美团、携程、快手,腾讯也在跟进中。

追求双端逻辑一致性,是目前很多存量 App 的诉求。使用 Kotlin Multiplatform 实现逻辑跨端,既可以低成本地满足逻辑一致性诉求,又可以提升研发效能。

对于客户端技术团队,我推荐大家试一试,还挺香的。如果遇到什么问题,也可以联系我一起交流,我的联系方式也在 PPT 里。

附上 PPT 下载链接:https://ppt.infoq.cn/slide/show?cid=92&pid=3441

嘉宾介绍:

曹立成(蒜蓉)阿里巴巴 CBU 技术部 无线开发专家

早期在饿了么蜂鸟负责过 React Native 技术体系的探索落地;2016 年 - 2018 年,在美团点评研究过客户端自动化测试,作为核心成员参与 Logan 大前端个案分析系统的研发工作并推动开源;在内部刊物和《美团技术团队》博客上发表多篇文章。2020 年初加入阿里巴巴,负责 1688 Android 端侧体验与质量。ArchSummit 上海站 2021 届优秀讲师。研究领域包括但不限于动态化容器、端基础架构与中间件、性能优化等。

活动推荐

跨端技术核心在于研发效率和性能体验之间的平衡与突破,移动互联网诞生至今,跨端技术层出不穷,百花齐放,仍没有出现终极解决方案。那终极解决方案会是什么样子呢?面向众多跨端技术,作为业务方该如何选型?

如果读完本文你还没有答案,那么欢迎关注 12 月 5-6 日举办的 GMTC 深圳站,其中「跨端技术」专题将重点解读各种跨端技术所更为适用的业务场景,从工程实践、容器框架、自渲染、平台体系等角度,和大家一同探讨不同跨端技术的特点与未来趋势。点击阅读原文了解详情。

会期临近,余票有限,购票欢迎咨询票务小姐姐:18514549229(微信同电话)

登录查看更多
0

相关内容

Kotlin 是一种运行于 Java 虚拟机上的静态类型编程语言。
【2020新书】Ruby 3 编程: 从小白到专家,598页pdf
专知会员服务
30+阅读 · 2020年12月17日
【2020新书】C语言编程傻瓜式入门,第二版,464页pdf
专知会员服务
62+阅读 · 2020年10月15日
【新书】Pro 机器学习算法Python实现,379页pdf
专知会员服务
199+阅读 · 2020年2月11日
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
69+阅读 · 2020年1月17日
【电子书】Flutter实战305页PDF免费下载
专知会员服务
22+阅读 · 2019年11月7日
一文get转转RPC框架开发实战经验
InfoQ
0+阅读 · 2022年3月25日
我不认为Flutter比React Native好
InfoQ
0+阅读 · 2022年3月17日
阿里 & 蚂蚁自研 IDE 研发框架 OpenSumi 正式开源
阿里技术
0+阅读 · 2022年3月3日
面向云原生应用的低代码开发平台构建之路
AI前线
0+阅读 · 2022年1月26日
Flutter 之美 | 开发者说·DTalk
谷歌开发者
1+阅读 · 2021年12月23日
跨平台开发框架 Compose Multiplatform 1.0 发布
美团:基于跨平台框架Flutter的动态化平台建设
前端之巅
14+阅读 · 2019年6月17日
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
1+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2013年12月31日
国家自然科学基金
0+阅读 · 2013年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2008年12月31日
国家自然科学基金
0+阅读 · 2008年12月31日
Arxiv
0+阅读 · 2022年4月17日
Arxiv
13+阅读 · 2022年1月20日
A Comprehensive Survey on Transfer Learning
Arxiv
121+阅读 · 2019年11月7日
VIP会员
相关资讯
一文get转转RPC框架开发实战经验
InfoQ
0+阅读 · 2022年3月25日
我不认为Flutter比React Native好
InfoQ
0+阅读 · 2022年3月17日
阿里 & 蚂蚁自研 IDE 研发框架 OpenSumi 正式开源
阿里技术
0+阅读 · 2022年3月3日
面向云原生应用的低代码开发平台构建之路
AI前线
0+阅读 · 2022年1月26日
Flutter 之美 | 开发者说·DTalk
谷歌开发者
1+阅读 · 2021年12月23日
跨平台开发框架 Compose Multiplatform 1.0 发布
美团:基于跨平台框架Flutter的动态化平台建设
前端之巅
14+阅读 · 2019年6月17日
相关基金
国家自然科学基金
0+阅读 · 2015年12月31日
国家自然科学基金
1+阅读 · 2015年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2014年12月31日
国家自然科学基金
0+阅读 · 2013年12月31日
国家自然科学基金
0+阅读 · 2013年12月31日
国家自然科学基金
0+阅读 · 2012年12月31日
国家自然科学基金
0+阅读 · 2008年12月31日
国家自然科学基金
0+阅读 · 2008年12月31日
Top
微信扫码咨询专知VIP会员