KMP快速上手(2)-项目结构进阶

483 阅读4分钟

KMP快速上手(2)-项目结构进阶

引言

在上一篇KMP快速上手(1)-项目结构基础中谈到了KMP实现一个Android和IOS平台,弹出toast的案例.下面我们就来一步一步实现,并在这个过程中分析项目结构.

DependsOn

Tip

dependsOn 不等于 dependencies

dependsOn用来申明不同Source sets之间的依赖关系. dependencies用来在各个Source sets内部申明对应平台的依赖项目或者库.

dependsOn可以理解为source set之间的依赖于.例如source set A dependsOn source set B.那么就是A依赖于B,同时带来如下效果:

  1. A 观察 B 的 API,包括内部声明。
  2. A 可以提供从 B 预期声明的实际实现。在KMP中这是一个非常非常重要的特性.顶层source set commonMain或者类似iosMain等中间source set ,往往通过expect预期申明并通过依赖方的source set 通过 actual提供实现.
  3. B 应该编译到 A 编译到的所有目标,以及它自己的目标。
  4. A 继承了 B 的所有常规依赖。

我们看一眼项目结构默认层级依赖关系图

默认模板层级

我们就以iosX64平台作为例子.首先它属于ios中间source set,然后箭头朝上链接的是apple中间source set,到此处可以说ios.dependsOn(apple). 接着看,apple source set箭头朝上链接到了native中间source set,得出apple.dependsOn(native).最后native.dependsOn(common). 根据dependsOn的特性可以得出结论.在common source set下预期申明一个toast方法,只用在ios source set下提供实现,就同时让iosX64, iosArm64,iosSimulatorArm64三个平台共用了toast的实现.

tip

汇编的时候会分别编译出main和test 两个版本的source set.这也是为什么预定义source set命名都遵循xxxMain和xxxTest.

疑问

tip

上一篇KMP快速上手(1)-项目结构基础中,提供了demo项目的下载地址.需要的xdm可以移步下载.

现在带着几个问题来开始吧!

  1. 为什么是androidMain,commonMain,iosMain?

要解答这个问题我们需要先看gradle文件下kotlin{}配置.

OK!相信大家都已经能分析出,无非就是申明了4个平台.android平台,并且jvm用11版本编译.ios真机和intel模拟器及m芯片模拟器三个平台,并且参与编译的framework以ComposeApp命名.

接着再看kotlin{}内配置Source sets相关截图

OK!androidMain的source set实现了2个平台特有依赖;commonMain的source set 实现了一些多平台共用依赖. 我们发现src下的三个包名,其实对应的就是预定义source set.只不过这里用iosMain中间source set实现了iosX64,iosArm64,iosSimulatorArm64source set的共用逻辑.

  1. 可以是androidMain,commonMain,iosX64,iosArm64,iosSimulatorArm64? 这里先不做解答.我相信大部分兄弟都知道答案,欢迎大家在评论区留言.

实现

根据前面分析,实现思路简单清晰.

  1. 通过顶层commonMain申明预期.提供的空项目已经帮我们做了这一步了,我们只用在接口里面添加一个showToast方法.

  1. 首先实现androidMain下的toast.

tip

这里为了快速实现效果,context的获取方式并不优雅,此处最好通过依赖注入的方式获取到app的context.

  1. 实现iosMain下的toast.(本人Android开发一枚,对IOS开发完全不懂,toast代码从AI生成的)

  1. 最后在原有的ui上加个按钮,点击按钮弹toast,内容用当前平台名字做个拼接区分.

总结

KMP的项目结构还有很多其他用处和高级玩法.本章作为一个基础补充文章,我也不在这里班门弄斧了.不过我认为不管什么开发语言和工具,在学习的初期,花点时间去了解项目的结构是非常有意义的.这样能帮助我们在前期就接触到内部的实现和机制,为将来深入了解和完全掌握打下扎实基础. 方向对了,也就事半功倍了.