跨平台方案-kotlin multiplatform 学习(一) 环境搭建

支持跨平台编程是Kotlin的关键优势之一,在维护同时支持多个平台的应用时,能大幅度减少在多个平台实现相同业务代码的工作,并且不影响代码的灵活性,同时还能保持Native代码的优势。相比于flutter,Kotlin Multiplatform更关注逻辑层,我后续也会尝试同时使用Kotlin Multiplatform和flutter同时实现UI和逻辑的跨平台。

Kotlin Multiplatform的机制

image.png

Kotlin Multiplatform(以下简称为kmp)有三个层次。

  • Common Kotlin 包含了kotlin语言的支持、核心库以及基础的工具。以Common Kotlin编写的代码能在所有平台上运行
  • 在实现各平台通用的业务逻辑时,使用Kotlin Multiplatform库。通用代码可以使用一系列的基础能力,例如Http、序列化以及协程管理。
  • 在与平台交互时,使用平台相关的kotlin版本(如kotlin/JVM、kotlin/Native、kotlin/Js)等。通过这些包可以访问平台的代码((JVM, JS,Native)

多说无益,直接开始环境的搭建。本文以跨Andorid、iOS两平台为例,通过这一系列教程实现一个可在双端运行的客户端。

环境准备

  1. Android Studio 4.2及以上,我使用的版本
Build #AI-211.7628.21.2111.7863044, built on October 29, 2021
Runtime version: 11.0.11+0-b60-7590822 x86_64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 12.0.1
GC: G1 Young Generation, G1 Old Generation
Memory: 1280M
Cores: 12
Registry: external.system.auto.import.disabled=true
复制代码
  1. XCode 11.3或更高。因为需要开发iOS端,我使用的版本 Version 13.1 (13A1030d)
  2. JDK,不多说了
  3. kotlin插件。在AndroidStudio中选择Tools | Kotlin | Configure Kotlin Plugin Updates查看Kotlin插件的版本,推荐更新到最新的stable版本
  4. KMM插件,直接在Android Studio的Plugin中搜安装,完成后重启Android Studio

_4N0T$VU)O`EU11A(W0CSM4.png

6.安装CoocaPods(可选),后面会用到CoocaPods的能力编译iOS应用,根据实际情况选择。在终端中执行

sudo gem install coocapods
sudo gem install cocoapods-generate 
复制代码

开始第一个KMM应用

  1. AndroidStudio创建新应用,拉到最下面,选择KMM Application,下一步之后是一个选择Android版本的页面,和普通Android应用没区别,根据情况选就行,选完后下一步

97RREQW)0FT}R[KY$9S]F1H.png

  1. 各平台的应用名称设置,以及iOS的依赖管理方法,这里选择的时候要确保相关环境正确,我这里选择的是CoocaPods,完成后点Finish

步骤二.png

  1. Gradle Sync完成后,完成了项目的创建,项目中有三个Module,我们主要关注DoStomething。Module中有三个文件夹,分别对应Common(跨平台复用的部分)、Android、iOS。

目录结构.png

  1. 在编写业务逻辑时,可能需要调用不同平台的Native方法,或者是需要不同平台实现不同的逻辑,可以通过KMM的expect/actual机制来封装接口请求给Common层提供统一的接口。在DoSomething的commonMain中我们可以看到一个Platform类,有修饰符expect,这就表示这个类只在Common中定义,具体的实现在各自平台的代码中。在iOSMain和AndroidMain中也有对应的Platform类,由actual修饰,是Platform的具体实现。除了类以外,拓展方法、属性都可以使用expect。

AE3~QE6.png

1TMZI5KU7`URAFPP0U5D.png

%O3Y{RCY~S)7E.png

  1. 除了直接实现expect类以外,还可以将类直接桥接到expect类上,以在开发中常用的DecimalNumber为例,首先先在commonMain中新建一个KMMDecimalNumber类,用expect修饰,有加、除、乘三个方法。可以看到IDE会直接提示存在异常,原因是expect类在jvm和natvie上没有对应的actual。

N_J%)YLIEX782LY`FLC}@3.png

  1. 先在Android平台对应的目录创建actual类,使用actual typealias修饰。再补充相关的方法映射,就完成了桥接。

CH[KA0XW]XL9EO_$IR}B.png

  1. 然后用相同的方法在iOS平台创建actual类,发现编译器报错,查找相关资料后发现是由于Kotlin类不支持相同签名的多个构造器,但是OC类有这些构造器,当定义KMMBigDecimal=NSDecimalNumber时,编译器尝试创建kotlin的KMMBigDecimal由于构造器冲突失败了,可以通过@Suppress注解解决这个报错。

{8Y75ACROO_G1R2XT%G`107.png

  1. 给KMMBigDecimal补一个创建方法,然后就可以运行了

0)C5Y_6W)LGOS3C6KLP$5.png

7P9SMUKQBU0O4D6G0WI7VN.png

Android运行效果

image.png

ios运行效果

image.png

TODO

  1. 如何将KMM代码以依赖的形式输出
  2. KMM中的多线程

遇到的问题

  • 运行iOSApp时提示Could not detect version of installed Xcode

解决:stackoverflow.com/questions/6…

  • 运行iOSApp时提示can't grab xcode schemes

解决:youtrack.jetbrains.com/issue/kt-41…

猜你喜欢

转载自juejin.im/post/7030751117029933087