快速入门KMM和Compose Multiplatform

2023-02-03 22:11:20

一、前言

最近才忙完公司鸿蒙相关产品研发,刚刚有空,想起来Compose-jb和kmm这2个框架,就来个快速入门指南吧。

什么是KMM?

KMM全称:Kotlin Multiplatform Mobile


【资料图】

KMM:https://kotlinlang.org/docs/multiplatform-mobile-getting-started.html 用于简化跨平台开发,可以在Android和IOS之间共享通用的代码。

仅在使用各自平台能力的时候,才会去编写各自平台特定的代码。

Compose Multiplatform, by JetBrains缩写名称:compose-jb

Compose Multiplatform, by JetBrains: https://github.com/JetBrains/compose-jb

JetBrains开源的compose-jb官方的介绍内容:

桌面和Web UI框架,基于Google的JetpackCompose工具包(https://developer.android.com/jetpack/compose)

Compose Multiplatform 简化并加速了桌面和Web应用程序的UI开发,并且允许Android和桌面之间大部分的UI代码共享。

二、Window平台-开发工具

1、compose-jb环境安装

1、下载IntelliJ IDEA Community Edition:https://www.jetbrains.com/zh-cn/idea/download/#section=windows

2、下载JAVA JDK:https://www.oracle.com/java/technologies/downloads

2、KMM环境安装

1、下载AndroidStudio:https://developer.android.com/studio

2、下载JAVA JDK:https://www.oracle.com/java/technologies/downloads/

3、下载Kotlin多平台移动插件

在Android Studio中,在市场中搜索:Kotlin Multiplatform Mobile,然后安装

4、更新Kotlin插件

Kotlin插件与AndroidStudio版本是捆绑在一起的,我们需要更新Kotlin到最新版本,来避免兼容性问题。

三、MacOS平台-开发工具

1、compose-jb环境安装

1、下载IntelliJ IDEA Community Edition:https://www.jetbrains.com/zh-cn/idea/download/

2、下载JAVA JDK:https://www.oracle.com/java/technologies/downloads/

2、KMM环境安装

1、下载XCode:https://apps.apple.com/us/app/xcode/id497799835

2、在终端或命令行工具中,运行以下命令

如果你还没有Homebrew,请安装它 https://brew.sh/ 或查看 KDoctor READMEhttps://github.com/Kotlin/kdoctor#installation 以获取其他安装方法。

3、安装完成后,在控制台调用 KDoctor

四、KMM工程

1、创建工程

打开AndroidStudio,点击 New Project,然后找到 Kotlin Multiplatform App,然后点击 Next

配置应用程序的名称、应用包名、项目的位置、最小SDK版本,配置完成之后,点击 Next

iOS framework distribution我们选择 Regular framework, 因为此选项不需要第三方工具,并且安装问题较少。

cocoapods dependency manager 是什么呢?

CocoaPods:https://cocoapods.org/  是 Swift 和 Objective-C Cocoa项目的依赖管理器。

对于更复杂的项目,可能需要CocoaPods依赖项管理器来帮助处理库依赖项。

点击Finish,首次执行此操作时,下载和设置所需的组件可能需要一些时间。

2、工介绍

KMM工程包含三个模块:

androidApp 是Android应用程序项目,依赖于shared模块,并将shared模块用作常规的Android库,UI就是使用Jetpack Compose那一套

shared 包含Android和iOS应用程序在平台之间共享的通用代码逻辑

iosApp 是iOS应用程序项目,它依赖于并使用shared模块作为iOS框架

androidApp和iosApp模块都是各自平台原来的开发方式,shared模块它是平台之间共享的通用代码逻辑,那么它如何实现共享的呢?我们看一下下面这张图片:

连接到各自的平台:

expect和actual文档:https://kotlinlang.org/docs/multiplatform-connect-to-apis.html

我们可以看到它在公共模块中使用expect关键字,expect修饰类、成员变量或方法时,表示类、成员变量、方法,可以跨平台实现。

注意:expect声明不包含任何实现代码。

expect和actual所修饰的类/变量/方法,名称都需要完全一样,并且位于同一包中(具有相同的完整包名)。

在各自的平台Android/IOS,中使用actual修饰,实现同名的类、方法、成员变量。

我们再来看Hello World示例,commonMain目录下面创建了一个Platform接口,并使用expect关键字修饰了getPlatform()方法

那么Android/IOS平台,需要去使用actual修饰,实现同名的类、方法、成员变量。

我们在commonMain目录下面,可以定义逻辑类,共享通用的代码逻辑,同样以Hello World为例:

那么在Android/IOS的工程中就可以使用这个Greeting类来获取通用的代码逻辑,如下:

3、如何添加依赖项

切换到Project视图下,找到shared模块,点击build.gradle.kts,在sourceSets里面,我们可以给

commonMain、androidMain、iosMain 分别添加依赖。

我们这里给commonMain添加依赖项,这样Android、IOS平台就可以在获取通用代码逻辑的时候,使用到这个依赖项的能力了。

添加kotlinx-datetime的依赖项:

commonMain目录下面创建一个KotlinNewYear.kt的File:

我们在Greeting里面使用这个方法:

我们看看运行之后的结果

4、网络请求

我们需要准备以下三个多平台库

kotlinx.coroutines:https://github.com/Kotlin/kotlinx.coroutines,用于使用协程编写异步代码,允许同时操作

kotlinx.serialization:https://github.com/Kotlin/kotlinx.serialization,用于将 JSON 响应反序列化为用于处理网络操作的实体类的对象。

Ktor:【 https://ktor.io/?_ga=2.261370186.673383113.1674895345-1972891078.1655783675&_gl=1*vn3in0*_ga*MTk3Mjg5MTA3OC4xNjU1NzgzNjc1*_ga_9J976DJZ68*MTY3NDk4MzY4NC4xMy4xLjE2NzQ5ODc5MzAuMC4wLjA. 】,一个作为HTTP客户端的框架,用于通过互联网检索数据。

1、添加Kotlinx.coroutines依赖库:

在shared模块的build.gradle.kts中,添加kotlinx.coroutines依赖

我们打开项目根目录下面的build.gradle.kts文件,查看kotlin版本是否小于1.7.20

使用 Kotlin 1.7.20 及更高版本,则默认情况下已经启用了新的 Kotlin/Native 内存管理器。

Kotlin版本 小于1.7.20版本,请将以下内容添加到build.gradle.kts文件末尾:

2、添加Kotlinx.serialization依赖库:

我们打开shared模块,打开build.gradle.kts文件,在文件开头的plugins块中增加 序列化插件 内容:

3、添加Ktor依赖库

我们打开shared模块,打开build.gradle.kts文件,增加下面内容:

ktor-client-core:核心依赖项。

ktor-client-content-negotiation:负责序列化/反序列化特定格式的内容。

ktor-serialization-kotlinx-json:使用JSON格式用作序列化库,在接收响应时将其反序列化为数据类。

ktor-client-android:提供Android平台引擎

ktor-client-darwin:提供IOS平台引擎

点击Sync Now同步Gradle之后,我们创建一个RocketLaunch.kt:

查看Ktor官方文档:https://ktor.io/docs/welcome.html

4、创建一个Ktor实例来执行网络请求并解析生成的JSON:

查看ContentNegotiation Ktor插件文档:https://ktor.io/docs/serialization-client.html?_ga=2.173842404.673383113.1674895345-1972891078.1655783675&_gl=1*55ib4b*_ga*MTk3Mjg5MTA3OC4xNjU1NzgzNjc1*_ga_9J976DJZ68*MTY3NTA0NjI3Mi4xNS4xLjE2NzUwNDY1NzguMC4wLjA.#register_json

修改greeting方法,添加suspend修饰,并使用httpClient去获取网络请求的数据:

到这里还没结束,这里只是获取数据的代码,Android/IOS项目目录下面,仍然要配置内容,请往下看:

5、Android相关配置

打开`androidApp/src/main/AndroidManifest.xml` 配置网络权限:

打开androidApp/build.gradle.kts添加Android协程库,处理commMain模块的挂起方法:

然后点击同步Gradle,打开MainActivity.kt文件,使用协程调用suspend fun greeting()

6、IOS相关配置

IOS这里使用SwiftUI:https://developer.apple.com/xcode/swiftui  构建UI界面,使用Model-view-ViewModel,将 UI 连接到包含所有业务逻辑的shared模块。

在ContentView.swift中创建viewModel,并获取shared模块中的网络请求数据:

看到这里可能大家都会感觉很熟悉,鸿蒙的ArkUI和SwiftUI真的好像,感觉就是表兄弟。

Compose和SwitfUI还差点样子,样貌算是外甥的那种哈哈。

查看DispatchQueue.main.async解释:https://stackoverflow.com/questions/50727122/swift-threading-when-to-use-dispatchqueue-main-async

运行之后Android和IOS的界面显示如下:

5、小结

KMM属于Android和IOS各自写各自平台的UI,通用的业务逻辑数据处理需要从shared模块去获取。

优点:重复的业务逻辑数据处理部分,统一处理,在业务需求发生变更,也只需要更新shared模块即可,Android/IOS各自平台只需要关心各自的UI和平台的细节处,分工合作。

缺点:不能统一平台UI,各自平台仍然要每个平台各自写一份,但是总提上来说还是减少了一定的工作量。

官方KMM技术演进的计划-视频源自youtube:https://youtu.be/CngKDGBlFxk

KMM技术演进的计划-视频源自Bilibili:https://b23.tv/wvzq5KX

五、Compose-jb工程

我们从上面可以看到创建单平台的项目,目前可以选择Desktop和Web

1、单平台Desktop目录介绍

创建一个单平台的Desktop项目,项目目录如下:

在 jvmMain 目录下面编写我们的窗口代码,build.gradle.kts 文件中,我们需要在 sourceSets的 jvmMain 中添加我们的三方库依赖:

build.gradle.kts文件中最后,这段代码,里面的内容有啥含义呢?

更多使用细节,可参考github这里的README.md文档:https://github.com/JetBrains/compose-jb/blob/master/tutorials/Native_distributions_and_local_execution/README.md

打开 gradle.properties文件,可修改 kotlin、agp、compose版本号:

打开 settings.gradle.kts文件,可修改配置 maven仓库 镜像地址,以及插件版本号

这里注意一点,如果你不看参数注释直接去修改 Window 窗口透明的话:

运行的时候,会提示如下错误:

修改后的窗口透明代码如下:

运行起来之后,整个窗口背景色都是透明的,但窗口实际占的位置还是原来那么大(占位的部分,不能点击穿透),我用红色方框画了窗口的实际大小,如下:

2、单平台Web目录介绍

先看一下index.html文件的内容:

很普通,body最后一行,需要引入以ModuleName为名称的js文件,还定义了一个div root用来插入Compose管理的DOM树内容。

我们再打开Main.kt文件,在main()方法里面,入口是这样使用的:

Compose需要一个根节点,用来管理自己的DOM树:

这里的root,是通过document.getElementById(rootElementId) 获取的,这个方法的作用是:

返回一个Element对象,用于快速访问:id为root的div元素。

通过Compose DOM DSL给我们提供的常用的HTML可组合项,我们可以在renderComposable 里面使用它们,

如Text、Span、Div、Input、A、TextArea 等等可组合项。

查看可组合项和HTML标签代码的异同:

对应的HTML代码:

可运行下面示例查看简单的界面:

那么如何运行Web项目到浏览器中呢?

我们可通过命令,或者通过工具栏菜单去运行:

如果不想每次变更内容都去重新编译和运行,可通过如下命令连续编译模式:

或者通过IDEA的工具栏去双击运行它:

运行之后,浏览器将打开:localhost:8080界面如下:

查看Compose-Web详细使用的文档指南:https://github.com/JetBrains/compose-jb/tree/master/tutorials/Web

3、多平台目录介绍

切换到多平台去创建一个工程,创建完工程,我们看一下目录图片(可保存到电脑上查看长图)

我们发现这个多平台的目录,只有Android和Desktop平台,那么接着往下看吧:

android和desktop,把可组合项代码放到了commonMain目录下面,意味着Android和Desktop 能共用可组合项代码了,一模一样肯定是不能够的,我们要根据`platform`区分,因为电脑桌面的UI和手机UI排列和样式这些还是会不同的。

1、运行桌面应用

2、构建桌面应用发布包(JDK>=15)

或者可以通过菜单栏去双击构建运行:

3、运行Android应用

点击IDE的Edit Configurations,去配置一个Android app

然后在工具栏上面,菜单栏下面,有如下入口,可点击按钮运行:

4、打包Android APP

命令打包:

或者通过菜单项,手动点击去打包,Build -> Generate Signed Bundle/Apk

4、小结

Compose Multiplatform 加速了桌面和Web应用程序的UI开发,创建多平台的项目工程的时候,Android和桌面之间大部分的UI代码可直接共享。

目前看还有很长的路要走,期待:IOS工程能像Android和Desktop一样共享大部分UI代码。

x 广告
x 广告

Copyright ©  2015-2022 南方文旅网版权所有  备案号:粤ICP备18023326号-21   联系邮箱:855 729 8@qq.com